ObjFW  Check-in [d8684fc232]

Overview
Comment:Add OFString (OFXMLUnescaping) category and API for OFXMLParser.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: d8684fc2321ed8fb306401b3335dabd5eb2f8da2a8e55f55a1cd355ba60750da
User & Date: js on 2009-07-14 18:57:38
Other Links: manifest | tags
Context
2009-07-14
21:22
Add of_string_unicode_to_utf8 which converts unicode to UTF-8. check-in: de937a62e4 user: js tags: trunk
18:57
Add OFString (OFXMLUnescaping) category and API for OFXMLParser. check-in: d8684fc232 user: js tags: trunk
17:51
Optimize some code by using the new stringWithCString:andLength: method. check-in: 7bb3494ef9 user: js tags: trunk
Changes

Modified src/Makefile from [ec70c1ba34] to [862b2d6a24].

22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
       ${OFPLUGIN_M}		\
       OFSocket.m		\
       OFStream.m		\
       OFString.m		\
       OFTCPSocket.m		\
       OFThread.m		\
       OFURLEncoding.m		\
       OFXMLElement.m


INCLUDESTMP := ${SRCS:.c=.h}
INCLUDES := ${INCLUDESTMP:.m=.h}	\
	    OFMacros.h			\
	    asprintf.h			\
	    objfw.h








|
>







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
       ${OFPLUGIN_M}		\
       OFSocket.m		\
       OFStream.m		\
       OFString.m		\
       OFTCPSocket.m		\
       OFThread.m		\
       OFURLEncoding.m		\
       OFXMLElement.m		\
       OFXMLParser.m

INCLUDESTMP := ${SRCS:.c=.h}
INCLUDES := ${INCLUDESTMP:.m=.h}	\
	    OFMacros.h			\
	    asprintf.h			\
	    objfw.h

Modified src/OFString.h from [1adde179e3] to [dedea52274].

199
200
201
202
203
204
205

- removeLeadingAndTrailingWhitespaces;
@end

#import "OFConstString.h"
#import "OFMutableString.h"
#import "OFURLEncoding.h"
#import "OFXMLElement.h"








>
199
200
201
202
203
204
205
206
- removeLeadingAndTrailingWhitespaces;
@end

#import "OFConstString.h"
#import "OFMutableString.h"
#import "OFURLEncoding.h"
#import "OFXMLElement.h"
#import "OFXMLParser.h"

Modified src/OFString.m from [b0bbce5a9e] to [c51d9e7bc3].

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 <sys/mman.h>
#else
#define madvise(addr, len, advise)
#endif

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

#import "asprintf.h"

/* References for static linking */
void _references_to_categories_of_OFString()
{
	_OFURLEncoding_reference = 1;
	_OFXMLElement_reference = 1;

};

int
of_string_check_utf8(const char *str, size_t len)
{
	size_t i;
	int utf8 = 0;







<
<










>







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
#include <sys/mman.h>
#else
#define madvise(addr, len, advise)
#endif

#import "OFString.h"
#import "OFAutoreleasePool.h"


#import "OFExceptions.h"
#import "OFMacros.h"

#import "asprintf.h"

/* References for static linking */
void _references_to_categories_of_OFString()
{
	_OFURLEncoding_reference = 1;
	_OFXMLElement_reference = 1;
	_OFXMLParser_reference = 1;
};

int
of_string_check_utf8(const char *str, size_t len)
{
	size_t i;
	int utf8 = 0;

Added src/OFXMLParser.h version [dba56f762f].









































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
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
/*
 * Copyright (c) 2008 - 2009
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of libobjfw. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import "OFObject.h"
#import "OFString.h"
#import "OFDictionary.h"

extern int _OFXMLParser_reference;

@class OFXMLParser;

@protocol OFXMLParserDelegate
-     (BOOL)xmlParser: (OFXMLParser*)parser
  didStartTagWithName: (OFString*)name
	    andPrefix: (OFString*)prefix
	 andNamespace: (OFString*)ns
	andAttributes: (OFDictionary*)attrs;
-   (BOOL)xmlParser: (OFXMLParser*)parser
  didEndTagWithName: (OFString*)name
	  andPrefix: (OFString*)prefix
       andNamespace: (OFString*)ns;
- (BOOL)xmlParser: (OFXMLParser*)parser
      foundString: (OFString*)string;
@end

@interface OFXMLParser: OFObject
{
	OFObject <OFXMLParserDelegate> *delegate;
	int state;
}

+ xmlParser;
- (id)delegate;
- setDelegate: (OFObject <OFXMLParserDelegate>*)delegate;
@end

@protocol OFXMLUnescapingDelegate
- (OFString*)foundUnknownEntityNamed: (OFString*)entitiy;
@end

@interface OFString (OFXMLUnescaping)
- stringByXMLUnescaping;
- stringByXMLUnescapingWithHandler: (OFObject <OFXMLUnescapingDelegate>*)h;
@end

Added src/OFXMLParser.m version [b77468664e].































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
 * Copyright (c) 2008 - 2009
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of libobjfw. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#include "config.h"

#include <string.h>

#import "OFXMLParser.h"
#import "OFAutoreleasePool.h"
#import "OFExceptions.h"

int _OFXMLParser_reference;

@implementation OFXMLParser
+ xmlParser
{
	return [[[self alloc] init] autorelease];
}

- (id)delegate
{
	return [[delegate retain] autorelease];
}

- setDelegate: (OFObject <OFXMLParserDelegate>*)delegate_
{
	[delegate release];
	delegate = [delegate_ retain];

	return self;
}
@end

@implementation OFString (OFXMLUnescaping)
- stringByXMLUnescaping
{
	return [self stringByXMLUnescapingWithHandler: nil];
}

- stringByXMLUnescapingWithHandler: (OFObject <OFXMLUnescapingDelegate>*)h
{
	size_t i, last;
	BOOL in_entity;
	OFString *ret;

	last = 0;
	in_entity = NO;
	ret = [OFMutableString string];

	for (i = 0; i < length; i++) {
		if (!in_entity && string[i] == '&') {
			[ret appendCStringWithoutUTF8Checking: string + last
						    andLength: i - last];

			last = i + 1;
			in_entity = YES;
		} else if (in_entity && string[i] == ';') {
			size_t len = i - last;

			if (len == 2 && !memcmp(string + last, "lt", 2))
				[ret appendString: @"<"];
			else if (len == 2 && !memcmp(string + last, "gt", 2))
				[ret appendString: @">"];
			else if (len == 4 && !memcmp(string + last, "quot", 4))
				[ret appendString: @"\""];
			else if (len == 4 && !memcmp(string + last, "apos", 4))
				[ret appendString: @"'"];
			else if (len == 3 && !memcmp(string + last, "amp", 3))
				[ret appendString: @"&"];
			else if (h != nil) {
				OFAutoreleasePool *pool;
				OFString *n, *tmp;

				pool = [[OFAutoreleasePool alloc] init];

				n = [OFString stringWithCString: string + last
						      andLength: len];
				tmp = [h foundUnknownEntityNamed: n];

				if (tmp == nil)
					@throw [OFInvalidEncodingException
					    newWithClass: isa];

				[ret appendString: tmp];
				[pool release];
			} else
				@throw [OFInvalidEncodingException
				    newWithClass: isa];

			last = i + 1;
			in_entity = NO;
		}
	}

	if (in_entity)
		@throw [OFInvalidEncodingException newWithClass: isa];

	[ret appendCStringWithoutUTF8Checking: string + last
				    andLength: i - last];

	return ret;
}
@end

Modified tests/OFString/OFString.m from [b1315ec8f9] to [b49062f26b].

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#ifndef _WIN32
#define ZD "%zd"
#else
#define ZD "%u"
#endif

#define NUM_TESTS 49
#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								\
	printf("\r\033[K\033[1;31mTest " ZD "/%d failed!\033[m\n",	\
	    i + 1, NUM_TESTS);						\







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

#ifndef _WIN32
#define ZD "%zd"
#else
#define ZD "%u"
#endif

#define NUM_TESTS 53
#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								\
	printf("\r\033[K\033[1;31mTest " ZD "/%d failed!\033[m\n",	\
	    i + 1, NUM_TESTS);						\
45
46
47
48
49
50
51













52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
		code;							\
		FAIL							\
	} @catch (exception *e) {					\
		SUCCESS							\
	}								\
	i++;














int
main()
{
	size_t i = 0;
	size_t j = 0;

	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFString *s1 = [OFMutableString stringWithCString: "test"];
	OFString *s2 = [OFMutableString stringWithCString: ""];
	OFString *s3;
	OFString *s4 = [OFMutableString string];
	OFArray *a;


	s3 = [s1 copy];

	CHECK([s1 isEqual: s3])
	CHECK(![s1 isEqual: [[OFObject alloc] init]])
	CHECK([s1 hash] == [s3 hash])








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












>







45
46
47
48
49
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
79
80
81
82
83
84
		code;							\
		FAIL							\
	} @catch (exception *e) {					\
		SUCCESS							\
	}								\
	i++;

@interface EntityHandler: OFObject <OFXMLUnescapingDelegate>
@end

@implementation EntityHandler
- (OFString*)foundUnknownEntityNamed: (OFString*)entity
{
	if ([entity isEqual: @"foo"])
		return @"bar";

	return nil;
}
@end

int
main()
{
	size_t i = 0;
	size_t j = 0;

	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFString *s1 = [OFMutableString stringWithCString: "test"];
	OFString *s2 = [OFMutableString stringWithCString: ""];
	OFString *s3;
	OFString *s4 = [OFMutableString string];
	OFArray *a;
	EntityHandler *h;

	s3 = [s1 copy];

	CHECK([s1 isEqual: s3])
	CHECK(![s1 isEqual: [[OFObject alloc] init]])
	CHECK([s1 hash] == [s3 hash])

172
173
174
175
176
177
178












179
180
181
182
	CHECK([[s2 removeTrailingWhitespaces] isEqual: @""])
	CHECK([[s3 removeLeadingAndTrailingWhitespaces] isEqual: @""])

	/* XML escaping tests */
	s1 = [@"<hello> &world'\"!&" stringByXMLEscaping];
	CHECK([s1 isEqual: @"&lt;hello&gt; &amp;world&apos;&quot;!&amp;"])













	puts("");

	return 0;
}







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




186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
	CHECK([[s2 removeTrailingWhitespaces] isEqual: @""])
	CHECK([[s3 removeLeadingAndTrailingWhitespaces] isEqual: @""])

	/* XML escaping tests */
	s1 = [@"<hello> &world'\"!&" stringByXMLEscaping];
	CHECK([s1 isEqual: @"&lt;hello&gt; &amp;world&apos;&quot;!&amp;"])

	/* XML unescaping tests */
	CHECK([[s1 stringByXMLUnescaping] isEqual: @"<hello> &world'\"!&"]);
	CHECK_EXCEPT([@"&foo;" stringByXMLUnescaping],
	    OFInvalidEncodingException)

	h = [[EntityHandler alloc] init];
	s1 = [@"x&foo;y" stringByXMLUnescapingWithHandler: h];
	CHECK([s1 isEqual: @"xbary"]);

	CHECK_EXCEPT([@"x&amp" stringByXMLUnescaping],
	    OFInvalidEncodingException)

	puts("");

	return 0;
}