Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -163,10 +163,23 @@ return ret; return *(char*)[obj item: [self items]] * -1; } } + +- (uint32_t)hash +{ + uint32_t hash; + size_t i; + + OF_HASH_INIT(hash); + for (i = 0; i < items * itemsize; i++) + OF_HASH_ADD(hash, ((char*)data)[i]); + OF_HASH_FINALIZE(hash); + + return hash; +} @end @implementation OFBigArray - initWithItemSize: (size_t)is { Index: src/OFMacros.h ================================================================== --- src/OFMacros.h +++ src/OFMacros.h @@ -40,5 +40,19 @@ #define OF_BSWAP_V(buf, len) #endif #define OF_ROL(val, bits) \ (((val) << (bits)) | ((val) >> (32 - (bits)))) + +#define OF_HASH_INIT(hash) hash = 0 +#define OF_HASH_ADD(hash, byte) \ + { \ + hash += byte; \ + hash += (hash << 10); \ + hash ^= (hash >> 6); \ + } +#define OF_HASH_FINALIZE(hash) \ + { \ + hash += (hash << 3); \ + hash ^= (hash >> 11); \ + hash += (hash << 15); \ + } Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -79,11 +79,11 @@ } - (uint32_t)hash { /* Classes containing data should reimplement this! */ - return (uint32_t)self & 0xFFFFFF; + return (uint32_t)self; } - addToMemoryPool: (void*)ptr { void **memchunks; Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -285,10 +285,23 @@ if (![obj isKindOf: [OFString class]]) @throw [OFInvalidArgumentException newWithClass: [self class]]; return strcmp(string, [obj cString]); } + +- (uint32_t)hash +{ + uint32_t hash; + size_t i; + + OF_HASH_INIT(hash); + for (i = 0; i < length; i++) + OF_HASH_ADD(hash, string[i]); + OF_HASH_FINALIZE(hash); + + return hash; +} - append: (OFString*)str { return [self appendCString: [str cString]]; } Index: tests/OFArray/OFArray.m ================================================================== --- tests/OFArray/OFArray.m +++ tests/OFArray/OFArray.m @@ -133,40 +133,50 @@ if (![x isEqual: y]) { puts("FAIL 1!"); return 1; } + + if ([x hash] != [y hash]) { + puts("FAIL 2!"); + return 1; + } [x add: "x"]; if ([x isEqual: y]) { - puts("FAIL 2!"); - return 2; + puts("FAIL 3!"); + return 1; } [pool releaseObjects]; x = [OFArray arrayWithItemSize: 2]; y = [OFArray bigArrayWithItemSize: 4]; if ([x isEqual: y]) { - puts("FAIL 3!"); + puts("FAIL 4!"); return 1; } [pool releaseObjects]; x = [OFArray arrayWithItemSize: 1]; [x addNItems: 3 fromCArray: "abc"]; y = [x copy]; if ([x compare: y]) { - puts("FAIL 4!"); + puts("FAIL 5!"); return 1; } [y add: "de"]; if ([x compare: y] != -100) { - puts("FAIL 5!"); + puts("FAIL 6!"); + return 1; + } + + if ([y hash] != 0xCD8B6206) { + puts("FAIL 7!"); return 1; } [pool release]; return 0; } Index: tests/OFString/OFString.m ================================================================== --- tests/OFString/OFString.m +++ tests/OFString/OFString.m @@ -23,11 +23,11 @@ #define ZD "%zd" #else #define ZD "%u" #endif -#define NUM_TESTS 13 +#define NUM_TESTS 15 #define SUCCESS \ printf("\r\033[1;%dmTests successful: " ZD "/%d\033[0m", \ (i == NUM_TESTS - 1 ? 32 : 33), i + 1, NUM_TESTS); \ fflush(stdout); #define FAIL \ @@ -62,17 +62,19 @@ OFString *s4 = [OFString string]; s3 = [s1 copy]; CHECK([s1 isEqual: s3]) - CHECK(![s1 isEqual: [OFObject new]]); + CHECK(![s1 isEqual: [OFObject new]]) + CHECK([s1 hash] == [s3 hash]) [s2 appendCString: "123"]; [s4 setTo: [s2 cString]]; CHECK(![s2 compare: s4]) CHECK(!strcmp([[s1 append: s2] cString], "test123")) + CHECK([s1 hash] == 0xC44F49A4) CHECK(strlen([s1 cString]) == [s1 length] && [s1 length] == 7) CHECK(!strcmp([[s1 reverse] cString], "321tset")) CHECK(!strcmp([[s1 upper] cString], "321TSET")) CHECK(!strcmp([[s1 lower] cString], "321tset"))