ObjFW  Check-in [35fda90cf5]

Overview
Comment:Add -[caseInsensitiveCompare:] and fix -[compare:].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 35fda90cf582abdbc01bbbf98c71f219f5fe1ef4621a87dd2e186f6624b61e8a
User & Date: js on 2009-11-13 14:30:06
Other Links: manifest | tags
Context
2009-11-13
18:29
Add -[hash] for OFList. check-in: eb67bc40fa user: js tags: trunk
14:30
Add -[caseInsensitiveCompare:] and fix -[compare:]. check-in: 35fda90cf5 user: js tags: trunk
2009-11-10
20:13
Fix a typo in TableGenerator.m and the resulting unicode.h. check-in: c628317621 user: js tags: trunk
Changes

Modified src/OFDataArray.m from [dff98ec80e] to [f5681d0dfa].

152
153
154
155
156
157
158

159
160
161
162
163
164
165
166
167


168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184

	return YES;
}

- (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
{







>








|
>
>
|
>
|
|
<
|
<
|


|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175

176
177
178
179
180
181
182
183
184
185
186

	return YES;
}

- (of_comparison_result_t)compare: (OFDataArray*)ary
{
	int cmp;
	size_t ary_count, min_count;

	if (![ary isKindOfClass: [OFDataArray class]])
		@throw [OFInvalidArgumentException newWithClass: isa
						       selector: _cmd];
	if ([ary itemsize] != itemsize)
		@throw [OFInvalidArgumentException newWithClass: isa
						       selector: _cmd];

	ary_count = [ary count];
	min_count = (count > ary_count ? ary_count : count);

	if ((cmp = memcmp(data, [ary cArray], min_count * itemsize)) == 0) {
		if (count > ary_count)
			return OF_ORDERED_DESCENDING;
		if (count < ary_count)

			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
	}

	if (cmp > 0)
		return OF_ORDERED_DESCENDING;
	else
		return OF_ORDERED_ASCENDING;
}

- (uint32_t)hash
{

Modified src/OFString.h from [a8cd4bc958] to [eec9378345].

204
205
206
207
208
209
210








211
212
213
214
215
216
217
 * Compares the OFString to another OFString.
 *
 * \param str A string to compare with
 * \return An of_comparison_result_t
 */
- (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
 */
- (of_unichar_t)characterAtIndex: (size_t)index;

/**







>
>
>
>
>
>
>
>







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
 * Compares the OFString to another OFString.
 *
 * \param str A string to compare with
 * \return An of_comparison_result_t
 */
- (of_comparison_result_t)compare: (OFString*)str;

/**
 * Compares the OFString to another OFString without caring about the case.
 *
 * \param str A string to compare with
 * \return An of_comparison_result_t
 */
- (of_comparison_result_t)caseInsensitiveCompare: (OFString*)str;

/**
 * \param index The index of the Unicode character to return
 * \return The Unicode character at the specified index
 */
- (of_unichar_t)characterAtIndex: (size_t)index;

/**

Modified src/OFString.m from [b097e022e5] to [dcfcc7e490].

24
25
26
27
28
29
30

31
32
33
34
35
36
37

#import "OFString.h"
#import "OFAutoreleasePool.h"
#import "OFExceptions.h"
#import "OFMacros.h"

#import "asprintf.h"


extern const uint16_t of_iso_8859_15[256];
extern const uint16_t of_windows_1252[256];

/* References for static linking */
void _references_to_categories_of_OFString()
{







>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

#import "OFString.h"
#import "OFAutoreleasePool.h"
#import "OFExceptions.h"
#import "OFMacros.h"

#import "asprintf.h"
#import "unicode.h"

extern const uint16_t of_iso_8859_15[256];
extern const uint16_t of_windows_1252[256];

/* References for static linking */
void _references_to_categories_of_OFString()
{
566
567
568
569
570
571
572



























573
574
575
576
577
578
579
580

581




582


583


584


585



586


587


588

589
590
591

592
593


594
595

596
597
598


599
600
601
602
603
604
605
{
	return [[OFMutableString alloc] initWithString: self];
}

- (of_comparison_result_t)compare: (OFString*)str
{
	int cmp;




























	if (![str isKindOfClass: [OFString class]])
		@throw [OFInvalidArgumentException newWithClass: isa
						       selector: _cmd];

	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;
	size_t i;








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





|
|
|
>
|
>
>
>
>
|
>
>
|
>
>
|
>
>

>
>
>
|
>
>
|
>
>
|
>
|

<
>

|
>
>
|
|
>

|

>
>







567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637

638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
{
	return [[OFMutableString alloc] initWithString: self];
}

- (of_comparison_result_t)compare: (OFString*)str
{
	int cmp;
	size_t str_len, min_len;

	if (![str isKindOfClass: [OFString class]])
		@throw [OFInvalidArgumentException newWithClass: isa
						       selector: _cmd];

	str_len = [str cStringLength];
	min_len = (length > str_len ? str_len : length);

	if ((cmp = memcmp(string, [str cString], min_len)) == 0) {
		if (length > str_len)
			return OF_ORDERED_DESCENDING;
		if (length < str_len)
			return OF_ORDERED_ASCENDING;
		return OF_ORDERED_SAME;
	}

	if (cmp > 0)
		return OF_ORDERED_DESCENDING;
	else
		return OF_ORDERED_ASCENDING;
}

- (of_comparison_result_t)caseInsensitiveCompare: (OFString*)str
{
	const char *str_cstr;
	size_t i, j, str_len;

	if (![str isKindOfClass: [OFString class]])
		@throw [OFInvalidArgumentException newWithClass: isa
						       selector: _cmd];

	str_cstr = [str cString];
	str_len = [str cStringLength];

	i = j = 0;

	while (i < length && j < str_len) {
		of_unichar_t c1, c2;
		size_t l1, l2;
		of_unichar_t tmp;

		l1 = of_string_utf8_to_unicode(string + i, length - i, &c1);
		l2 = of_string_utf8_to_unicode(str_cstr + j, str_len - j, &c2);

		if (l1 == 0 || l2 == 0 || c1 > 0x10FFFF || c2 > 0x10FFFF)
			@throw [OFInvalidEncodingException newWithClass: isa];

		if (c1 >> 8 < OF_UNICODE_CASEFOLDING_TABLE_SIZE) {
			tmp = of_unicode_casefolding_table[c1 >> 8][c1 & 0xFF];

			if (tmp != 0)
				c1 = tmp;
		}

		if (c2 >> 8 < OF_UNICODE_CASEFOLDING_TABLE_SIZE) {
			tmp = of_unicode_casefolding_table[c2 >> 8][c2 & 0xFF];

			if (tmp != 0)
				c2 = tmp;
		}

		if (c1 > c2)
			return OF_ORDERED_DESCENDING;

		if (c1 < c2)
			return OF_ORDERED_ASCENDING;

		i += l1;
		j += l2;
	}

	if (length - i > str_len - j)
		return OF_ORDERED_DESCENDING;
	else if (length - i < str_len - j)
		return OF_ORDERED_ASCENDING;

	return OF_ORDERED_SAME;
}

- (uint32_t)hash
{
	uint32_t hash;
	size_t i;

Modified tests/OFDataArray.m from [1c9d8d3ad2] to [9aaf176836].

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

static OFString *module;
const char *str = "Hello!";

static void
do_tests(Class class)
{
	OFDataArray *array[2];
	void *data[2];
	Class other;

	TEST(@"+[dataArrayWithItemSize:]",
	    (array[0] = [class dataArrayWithItemSize: 4096]))

	data[0] = [array[0] allocMemoryWithSize: 4096];







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

static OFString *module;
const char *str = "Hello!";

static void
do_tests(Class class)
{
	OFDataArray *array[4];
	void *data[2];
	Class other;

	TEST(@"+[dataArrayWithItemSize:]",
	    (array[0] = [class dataArrayWithItemSize: 4096]))

	data[0] = [array[0] allocMemoryWithSize: 4096];
57
58
59
60
61
62
63





64
65
66
67

68
69
70
71
72
73
74
		     fromCArray: [array[0] cArray]] &&
	    [array[1] isEqual: array[0]] &&
	    [array[1] removeNItems: 1] && ![array[0] isEqual: array[1]])

	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]] == OF_ORDERED_DESCENDING &&
	    [array[1] compare: array[0]] == OF_ORDERED_ASCENDING)


	TEST(@"-[hash]", [array[0] hash] == 0xC54621B6)

	TEST(@"-[removeNItems:]", [array[0] removeNItems: 1])

	TEST(@"Building strings",
	    (array[0] = [class dataArrayWithItemSize: 1]) &&







>
>
>
>
>



|
>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
		     fromCArray: [array[0] cArray]] &&
	    [array[1] isEqual: array[0]] &&
	    [array[1] removeNItems: 1] && ![array[0] isEqual: array[1]])

	TEST(@"-[copy]", (array[1] = [[array[0] copy] autorelease]) &&
	    [array[0] isEqual: array[1]])

	array[2] = [OFDataArray dataArrayWithItemSize: 1];
	array[3] = [OFDataArray dataArrayWithItemSize: 1];
	[array[2] addItem: "a"];
	[array[2] addItem: "a"];
	[array[3] addItem: "z"];
	TEST(@"-[compare]", [array[0] compare: array[1]] == 0 &&
	    [array[1] removeNItems: 1] &&
	    [array[0] compare: array[1]] == OF_ORDERED_DESCENDING &&
	    [array[1] compare: array[0]] == OF_ORDERED_ASCENDING &&
	    [array[2] compare: array[3]] == OF_ORDERED_ASCENDING)

	TEST(@"-[hash]", [array[0] hash] == 0xC54621B6)

	TEST(@"-[removeNItems:]", [array[0] removeNItems: 1])

	TEST(@"Building strings",
	    (array[0] = [class dataArrayWithItemSize: 1]) &&

Modified tests/OFString.m from [335c787098] to [5db36dc58d].

50
51
52
53
54
55
56
57














58
59
60
61
62
63
64
	s[1] = [OFMutableString string];
	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]] == 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:]",
	    [s[1] appendCString: "1𝄞"] && [s[1] appendString: @"3"] &&
	    [[s[0] appendString: s[1]] isEqual: @"täs€1𝄞3"])







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
	s[1] = [OFMutableString string];
	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]] == OF_ORDERED_SAME &&
	    [s[0] compare: @""] != OF_ORDERED_SAME &&
	    [@"" compare: @"a"] == OF_ORDERED_ASCENDING &&
	    [@"a" compare: @"b"] == OF_ORDERED_ASCENDING &&
	    [@"cd" compare: @"bc"] == OF_ORDERED_DESCENDING &&
	    [@"ä" compare: @"ö"] == OF_ORDERED_ASCENDING &&
	    [@"€" compare: @"ß"] == OF_ORDERED_DESCENDING &&
	    [@"aa" compare: @"z"] == OF_ORDERED_ASCENDING)

	TEST(@"-[caseInsensitiveCompare:]",
	    [@"a" caseInsensitiveCompare: @"A"] == OF_ORDERED_SAME &&
	    [@"Ä" caseInsensitiveCompare: @"ä"] == OF_ORDERED_SAME &&
	    [@"я" caseInsensitiveCompare: @"Я"] == OF_ORDERED_SAME &&
	    [@"€" caseInsensitiveCompare: @"ß"] == OF_ORDERED_DESCENDING &&
	    [@"ß" caseInsensitiveCompare: @"→"] == OF_ORDERED_ASCENDING &&
	    [@"AA" caseInsensitiveCompare: @"z"] == OF_ORDERED_ASCENDING)

	TEST(@"-[hash] is the same if -[isEqual:] is YES",
	    [s[0] hash] == [s[2] hash])

	TEST(@"-[appendString:] and -[appendCString:]",
	    [s[1] appendCString: "1𝄞"] && [s[1] appendString: @"3"] &&
	    [[s[0] appendString: s[1]] isEqual: @"täs€1𝄞3"])