summaryrefslogtreecommitdiff
path: root/plugins/ShellExt/src/utils.cpp
blob: 275224388e4b74309be665b8b821efa4973f0784 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "stdafx.h"

#ifdef LOG_ENABLED
extern wchar_t tszLogPath[];

void logA(const char *format, ...)
{
	FILE *out = _wfopen(tszLogPath, L"a+");
	if (out) {
		va_list args;
		va_start(args, format);
		vfprintf(out, format, args);
		va_end(args);
		fclose(out);
	}
}
#endif

///////////////////////////////////////////////////////////////////////////////

UINT murmur_hash(const char *str)
{
	size_t len = lstrlenA(str);

	// 'm' and 'r' are mixing constants generated offline.
	// They're not really 'magic', they just happen to work well.
	const unsigned int m = 0x5bd1e995;
	const int r = 24;

	// Initialize the hash to a 'random' value
	unsigned int h = (unsigned)len;

	// Mix 4 bytes at a time into the hash
	const unsigned char *data = (const unsigned char*)str;

	while (len >= 4) {
		unsigned int k = *(unsigned int*)data;

		k *= m;
		k ^= k >> r;
		k *= m;

		h *= m;
		h ^= k;

		data += 4;
		len -= 4;
	}

	// Handle the last few bytes of the input array
	switch(len) {
	case 3: h ^= data[2] << 16;
	case 2: h ^= data[1] << 8;
	case 1: h ^= data[0];
			h *= m;
	}

	// Do a few final mixes of the hash to ensure the last few
	// bytes are well-incorporated.
	h ^= h >> 13;
	h *= m;
	h ^= h >> 15;

	return h;
}