ObjFW  Check-in [f9ed4c1d11]

Overview
Comment:Optimize handling of ASCII strings.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: f9ed4c1d1157ac0fa85df8c9da40c0acafa520f84f9fa5210121095ec295fd0f
User & Date: js on 2010-09-19 22:59:16
Other Links: manifest | tags
Context
2010-09-20
01:18
Prefix utils in if we're doing a crosscompile. check-in: 85e9a7540c user: js tags: trunk
2010-09-19
22:59
Optimize handling of ASCII strings. check-in: f9ed4c1d11 user: js tags: trunk
22:39
Add -[typeEncodingForSelector] and +[typeEncodingForInstanceSelector:]. check-in: 477d06da14 user: js tags: trunk
Changes

Modified src/OFConstantString.m from [d070e3d08a] to [1e07f47851].

83
84
85
86
87
88
89





90
91
92
93
94
95
96
}

- initWithString: (OFString*)str
{
	@throw [OFNotImplementedException newWithClass: isa
					      selector: _cmd];
}






- (void)addMemoryToPool: (void*)ptr
{
	@throw [OFNotImplementedException newWithClass: isa
					      selector: _cmd];
}








>
>
>
>
>







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
}

- initWithString: (OFString*)str
{
	@throw [OFNotImplementedException newWithClass: isa
					      selector: _cmd];
}

- (BOOL)isUTF8
{
	return YES;
}

- (void)addMemoryToPool: (void*)ptr
{
	@throw [OFNotImplementedException newWithClass: isa
					      selector: _cmd];
}

Modified src/OFString.h from [0db9d52d0e] to [5350934922].

263
264
265
266
267
268
269




270
271
272
273
274
275
276
 */
- (size_t)length;

/**
 * \return The length of the string which cString would return
 */
- (size_t)cStringLength;





/**
 * Compares the OFString to another OFString.
 *
 * \param str A string to compare with
 * \return An of_comparison_result_t
 */







>
>
>
>







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
 */
- (size_t)length;

/**
 * \return The length of the string which cString would return
 */
- (size_t)cStringLength;

/// \cond internal
- (BOOL)isUTF8;
/// \endcond

/**
 * Compares the OFString to another OFString.
 *
 * \param str A string to compare with
 * \return An of_comparison_result_t
 */

Modified src/OFString.m from [2b9702d139] to [4289e64de5].

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
#include "config.h"

#define _GNU_SOURCE
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include <sys/stat.h>
#ifdef HAVE_MADVISE
# include <sys/mman.h>
#else
# define madvise(addr, len, advise)
#endif

#import "OFString.h"
#import "OFArray.h"
#import "OFFile.h"
#import "OFAutoreleasePool.h"
#import "OFExceptions.h"
#import "macros.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()
{
	_OFString_Hashing_reference = 1;
	_OFString_URLEncoding_reference = 1;
	_OFString_XMLEscaping_reference = 1;







>




















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







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
#include "config.h"

#define _GNU_SOURCE
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <sys/stat.h>
#ifdef HAVE_MADVISE
# include <sys/mman.h>
#else
# define madvise(addr, len, advise)
#endif

#import "OFString.h"
#import "OFArray.h"
#import "OFFile.h"
#import "OFAutoreleasePool.h"
#import "OFExceptions.h"
#import "macros.h"

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

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

static inline int
memcasecmp(const char *s1, const char *s2, size_t len)
{
	size_t i;

	for (i = 0; i < len; i++) {
		if (tolower(s1[i]) > tolower(s2[i]))
			return OF_ORDERED_DESCENDING;
		if (tolower(s1[i]) < tolower(s2[i]))
			return OF_ORDERED_ASCENDING;
	}

	return OF_ORDERED_SAME;
}

/* References for static linking */
void _references_to_categories_of_OFString()
{
	_OFString_Hashing_reference = 1;
	_OFString_URLEncoding_reference = 1;
	_OFString_XMLEscaping_reference = 1;
698
699
700
701
702
703
704





705
706
707
708
709
710
711
	return of_string_position_to_index(string, length);
}

- (size_t)cStringLength
{
	return length;
}






- (BOOL)isEqual: (OFObject*)obj
{
	if (![obj isKindOfClass: [OFString class]])
		return NO;
	if (strcmp(string, [(OFString*)obj cString]))
		return NO;







>
>
>
>
>







714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
	return of_string_position_to_index(string, length);
}

- (size_t)cStringLength
{
	return length;
}

- (BOOL)isUTF8
{
	return isUTF8;
}

- (BOOL)isEqual: (OFObject*)obj
{
	if (![obj isKindOfClass: [OFString class]])
		return NO;
	if (strcmp(string, [(OFString*)obj cString]))
		return NO;
721
722
723
724
725
726
727
728
729

730
731
732
733
734
735
736
- mutableCopy
{
	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);







<

>







742
743
744
745
746
747
748

749
750
751
752
753
754
755
756
757
- mutableCopy
{
	return [[OFMutableString alloc] initWithString: self];
}

- (of_comparison_result_t)compare: (OFString*)str
{

	size_t str_len, min_len;
	int cmp;

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

	str_len = [str cStringLength];
	min_len = (length > str_len ? str_len : length);
748
749
750
751
752
753
754
755

756
757
758
759
760
761
762

















763
764
765
766
767
768
769
	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;








|
>







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







769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
	else
		return OF_ORDERED_ASCENDING;
}

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

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

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

	if (![self isUTF8]) {
		min_len = (length > str_len ? str_len : length);

		if ((cmp = memcasecmp(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;
	}

	i = j = 0;

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

818
819
820
821
822
823
824







825
826
827
828
829
830
831

	return hash;
}

- (of_unichar_t)characterAtIndex: (size_t)index
{
	of_unichar_t c;








	index = of_string_index_to_position(string, index, length);

	if (index >= length)
		@throw [OFOutOfRangeException newWithClass: isa];

	if (!of_string_utf8_to_unicode(string + index, length - index, &c))







>
>
>
>
>
>
>







857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877

	return hash;
}

- (of_unichar_t)characterAtIndex: (size_t)index
{
	of_unichar_t c;

	if (![self isUTF8]) {
		if (index >= length)
			@throw [OFOutOfRangeException newWithClass: isa];

		return string[index];
	}

	index = of_string_index_to_position(string, index, length);

	if (index >= length)
		@throw [OFOutOfRangeException newWithClass: isa];

	if (!of_string_utf8_to_unicode(string + index, length - index, &c))
874
875
876
877
878
879
880

881
882

883
884
885
886
887
888
889
			return SIZE_MAX;
	}
}

- (OFString*)substringFromIndex: (size_t)start
			toIndex: (size_t)end
{

	start = of_string_index_to_position(string, start, length);
	end = of_string_index_to_position(string, end, length);


	if (start > end)
		@throw [OFInvalidArgumentException newWithClass: isa
						       selector: _cmd];

	if (end > length)
		@throw [OFOutOfRangeException newWithClass: isa];







>
|
|
>







920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
			return SIZE_MAX;
	}
}

- (OFString*)substringFromIndex: (size_t)start
			toIndex: (size_t)end
{
	if ([self isUTF8]) {
		start = of_string_index_to_position(string, start, length);
		end = of_string_index_to_position(string, end, length);
	}

	if (start > end)
		@throw [OFInvalidArgumentException newWithClass: isa
						       selector: _cmd];

	if (end > length)
		@throw [OFOutOfRangeException newWithClass: isa];

Modified tests/OFStringTests.m from [ae4138d157] to [f13f57a01e].

70
71
72
73
74
75
76
77


78
79
80
81
82
83
84

	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:]",
	    R([s[1] appendCString: "1𝄞"]) && R([s[1] appendString: @"3"]) &&
	    R([s[0] appendString: s[1]]) && [s[0] isEqual: @"täs€1𝄞3"])







|
>
>







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

	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 &&
	    [[OFString stringWithCString: "ABC"] caseInsensitiveCompare:
	    [OFString stringWithCString: "AbD"]] == [@"abc" compare: @"abd"])

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

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