Go to the documentation of this file.00001
00002 #include "Hashcode.h"
00003
00004 namespace castor {
00005
00006 void Hashcode::mix(unsigned int *a, unsigned int *b, unsigned int *c) {
00007 *a -= *b; *a -= *c; *a ^= (*c >> 13);
00008 *b -= *c; *b -= *a; *b ^= (*a << 8);
00009 *c -= *a; *c -= *b; *c ^= (*b >> 13);
00010 *a -= *b; *a -= *c; *a ^= (*c >> 12);
00011 *b -= *c; *b -= *a; *b ^= (*a << 16);
00012 *c -= *a; *c -= *b; *c ^= (*b >> 5);
00013 *a -= *b; *a -= *c; *a ^= (*c >> 3);
00014 *b -= *c; *b -= *a; *b ^= (*a << 10);
00015 *c -= *a; *c -= *b; *c ^= (*b >> 15);
00016 }
00017
00018 unsigned int Hashcode::compute(const unsigned char *data, size_t len) {
00019
00020 unsigned int a = 0x9e3779b9;
00021 unsigned int b = 0x9e3779b9;
00022 unsigned int c = 0;
00023
00024 size_t i = 0;
00025
00026 while (i + 12 <= len) {
00027 a += (unsigned int)data[i] |
00028 ((unsigned int)data[i + 1] << 8) |
00029 ((unsigned int)data[i + 2] << 16) |
00030 ((unsigned int)data[i + 3] << 24);
00031 i += 4;
00032 b += (unsigned int)data[i] |
00033 ((unsigned int)data[i + 1] << 8) |
00034 ((unsigned int)data[i + 2] << 16) |
00035 ((unsigned int)data[i + 3] << 24);
00036 i += 4;
00037 c += (unsigned int)data[i] |
00038 ((unsigned int)data[i + 1] << 8) |
00039 ((unsigned int)data[i + 2] << 16) |
00040 ((unsigned int)data[i + 3] << 24);
00041 i += 4;
00042
00043 mix(&a, &b, &c);
00044 }
00045
00046 c += len;
00047
00048 if (i < len) { a += data[i++]; }
00049 if (i < len) { a += (unsigned int)data[i++] << 8; }
00050 if (i < len) { a += (unsigned int)data[i++] << 16; }
00051 if (i < len) { a += (unsigned int)data[i++] << 24; }
00052 if (i < len) { b += (unsigned int)data[i++]; }
00053 if (i < len) { b += (unsigned int)data[i++] << 8; }
00054 if (i < len) { b += (unsigned int)data[i++] << 16; }
00055 if (i < len) { b += (unsigned int)data[i++] << 24; }
00056 if (i < len) { c += (unsigned int)data[i++] << 8; }
00057 if (i < len) { c += (unsigned int)data[i++] << 16; }
00058 if (i < len) { c += (unsigned int)data[i++] << 24; }
00059
00060 mix(&a, &b, &c);
00061
00062 return c;
00063 }
00064
00065
00066 int hashcode(bool x) { return Hashcode::compute((unsigned char *)&x, 1); }
00067 int hashcode(char x) { return Hashcode::compute((unsigned char *)&x, 1); }
00068 int hashcode(unsigned char x) { return Hashcode::compute((unsigned char *)&x, 1); }
00069 int hashcode(short x) { return Hashcode::compute((unsigned char *)&x, 2); }
00070 int hashcode(unsigned short x) { return Hashcode::compute((unsigned char *)&x, 2); }
00071 int hashcode(long x) { return Hashcode::compute((unsigned char *)&x, 4); }
00072 int hashcode(unsigned long x) { return Hashcode::compute((unsigned char *)&x, 4); }
00073 int hashcode(long long x) { return Hashcode::compute((unsigned char *)&x, 8); }
00074 int hashcode(unsigned long long x) { return Hashcode::compute((unsigned char *)&x, 8); }
00075 int hashcode(float x) { return Hashcode::compute((unsigned char *)&x, 4); }
00076 int hashcode(double x) { return Hashcode::compute((unsigned char *)&x, 8); }
00077 int hashcode(const std::string x) { return Hashcode::compute((unsigned char *)x.c_str(), x.size()); }
00078
00079 int hashcode(const castor::net::NetAddress &a) {
00080 BytesPtr b = a.getBytes();
00081 return Hashcode::compute((unsigned char *)&(*b)[0], b->size());
00082 }
00083
00084 }
00085