Index: src/OFDataArray.h ================================================================== --- src/OFDataArray.h +++ src/OFDataArray.h @@ -58,15 +58,14 @@ - (void*)cArray; /** * Compares the OFDataArray to another object. * - * \param obj An object to compare with - * \return An integer which is the result of the comparison, see for example - * strcmp + * \param ary A data array to compare with + * \return An of_comparsion_result_t */ -- (int)compare: (id)obj; +- (of_comparison_result_t)compare: (OFDataArray*)obj; /** * Returns a specific item of the OFDataArray. * * \param index The number of the item to return Index: src/OFDataArray.m ================================================================== --- src/OFDataArray.m +++ src/OFDataArray.m @@ -151,35 +151,35 @@ return NO; return YES; } -- (int)compare: (id)obj -{ - int ret; - - if (![obj isKindOfClass: [OFDataArray class]]) - @throw [OFInvalidArgumentException newWithClass: isa - selector: _cmd]; - if ([obj itemsize] != itemsize) - @throw [OFInvalidArgumentException newWithClass: isa - selector: _cmd]; - - if ([obj count] == count) - return memcmp(data, [obj cArray], count * itemsize); - - if (count > [obj count]) { - if ((ret = memcmp(data, [obj cArray], [obj count] * itemsize))) - return ret; - - return *(char*)[self itemAtIndex: [obj count]]; - } else { - if ((ret = memcmp(data, [obj cArray], count * itemsize))) - return ret; - - return *(char*)[obj itemAtIndex: count] * -1; - } +- (of_comparison_result_t)compare: (OFDataArray*)ary +{ + int cmp; + + if (![ary isKindOfClass: [OFDataArray class]]) + @throw [OFInvalidArgumentException newWithClass: isa + selector: _cmd]; + if ([ary itemsize] != itemsize) + @throw [OFInvalidArgumentException newWithClass: isa + selector: _cmd]; + + if ([ary count] == count) { + if ((cmp = memcmp(data, [ary cArray], count * itemsize)) == 0) + return OF_ORDERED_SAME; + + if (cmp > 0) + return OF_ORDERED_DESCENDING; + else + return OF_ORDERED_ASCENDING; + } + + if (count > [ary count]) + return OF_ORDERED_DESCENDING; + else + return OF_ORDERED_ASCENDING; } - (uint32_t)hash { uint32_t hash; Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -20,10 +20,22 @@ #import #ifndef __objc_INCLUDE_GNU #import #endif +/** + * A result of a comparison. + */ +typedef enum { + /// The left object is smaller than the right + OF_ORDERED_ASCENDING = -1, + /// Both objects are equal + OF_ORDERED_SAME = 0, + /// The left object is bigger than the right + OF_ORDERED_DESCENDING = 1 +} of_comparison_result_t; + /** * The OFObject class is the base class for all other classes inside ObjFW. */ @interface OFObject { Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -201,17 +201,16 @@ * \return The length of the string which cString would return */ - (size_t)cStringLength; /** - * Compares the OFString to another object. + * Compares the OFString to another OFString. * - * \param obj An object to compare with - * \return An integer which is the result of the comparison, see for example - * strcmp + * \param str A string to compare with + * \return An of_comparison_result_t */ -- (int)compare: (id)obj; +- (of_comparison_result_t)compare: (OFString*)str; /** * \param index The index of the Unicode character to return * \return The Unicode character at the specified index */ Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -560,17 +560,39 @@ - (id)mutableCopy { return [[OFMutableString alloc] initWithString: self]; } -- (int)compare: (id)obj +- (of_comparison_result_t)compare: (OFString*)str { - if (![obj isKindOfClass: [OFString class]]) + int cmp; + + if (![str isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; - return strcmp(string, [obj cString]); + if ([str length] == [self length]) { + if (length != [str cStringLength]) { + if (length > [str cStringLength]) + return OF_ORDERED_DESCENDING; + else + return OF_ORDERED_ASCENDING; + } + + if ((cmp = memcmp(string, [str cString], length)) == 0) + return OF_ORDERED_SAME; + + if (cmp > 0) + return OF_ORDERED_DESCENDING; + else + return OF_ORDERED_ASCENDING; + } + + if ([self length] > [str length]) + return OF_ORDERED_DESCENDING; + else + return OF_ORDERED_ASCENDING; } - (uint32_t)hash { uint32_t hash; Index: tests/OFDataArray.m ================================================================== --- tests/OFDataArray.m +++ tests/OFDataArray.m @@ -61,12 +61,12 @@ TEST(@"-[copy]", (array[1] = [[array[0] copy] autorelease]) && [array[0] isEqual: array[1]]) TEST(@"-[compare]", [array[0] compare: array[1]] == 0 && [array[1] removeNItems: 1] && - [array[0] compare: array[1]] == 0x42 && - [array[1] compare: array[0]] == -0x42) + [array[0] compare: array[1]] == OF_ORDERED_DESCENDING && + [array[1] compare: array[0]] == OF_ORDERED_ASCENDING) TEST(@"-[hash]", [array[0] hash] == 0xC54621B6) TEST(@"-[removeNItems:]", [array[0] removeNItems: 1]) Index: tests/OFString.m ================================================================== --- tests/OFString.m +++ tests/OFString.m @@ -51,12 +51,12 @@ s[2] = [[s[0] copy] autorelease]; TEST(@"-[isEqual:]", [s[0] isEqual: s[2]] && ![s[0] isEqual: [[[OFObject alloc] init] autorelease]]) - TEST(@"-[compare:]", [s[0] compare: s[2]] == 0 && - [s[0] compare: @""] != 0) + TEST(@"-[compare:]", [s[0] compare: s[2]] == OF_ORDERED_SAME && + [s[0] compare: @""] != OF_ORDERED_SAME) TEST(@"-[hash] is the same if -[isEqual:] is YES", [s[0] hash] == [s[2] hash]) TEST(@"-[appendString:] and -[appendCString:]",