ObjFW  Check-in [ad93296956]

Overview
Comment:Add OFXMLElementBuilder.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ad93296956f3abf549450316920b9a2c433609545f946d16202229aca774042b
User & Date: js on 2010-07-02 21:40:56
Other Links: manifest | tags
Context
2010-07-02
21:56
Add -[writeToFile:] to OFString. check-in: aed0aea0b2 user: js tags: trunk
21:40
Add OFXMLElementBuilder. check-in: ad93296956 user: js tags: trunk
21:05
Rename +[xmlParser] to +[parser]. check-in: c1f392e534 user: js tags: trunk
Changes

Modified src/Makefile from [861c5b4d8f] to [42133a0ca4].

32
33
34
35
36
37
38

39
40
41
42
43
44
45
       OFString+URLEncoding.m	\
       OFString+XMLEscaping.m	\
       OFString+XMLUnescaping.m	\
       OFTCPSocket.m		\
       ${OFTHREAD_M}		\
       OFXMLAttribute.m		\
       OFXMLElement.m		\

       OFXMLParser.m		\
       unicode.m

INCLUDES := ${SRCS:.m=.h}	\
	    ObjFW.h		\
	    asprintf.h		\
	    ${ATOMIC_H}		\







>







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
       OFString+URLEncoding.m	\
       OFString+XMLEscaping.m	\
       OFString+XMLUnescaping.m	\
       OFTCPSocket.m		\
       ${OFTHREAD_M}		\
       OFXMLAttribute.m		\
       OFXMLElement.m		\
       OFXMLElementBuilder.m	\
       OFXMLParser.m		\
       unicode.m

INCLUDES := ${SRCS:.m=.h}	\
	    ObjFW.h		\
	    asprintf.h		\
	    ${ATOMIC_H}		\

Added src/OFXMLElementBuilder.h version [d870539158].















































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * Copyright (c) 2008 - 2010
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. 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"

@class OFMutableArray;
@class OFXMLElement;
@class OFXMLElementBuilder;

/**
 * \brief A protocol that needs to be implemented by delegates for
 * OFXMLElementBuilder.
 */
@protocol OFXMLElementBuilderDelegate
/**
 * This callback is called when the OFXMLElementBuilder built an element.
 *
 * If the OFXMLElementBuilder was used as a delegate for the OFXMLParser since
 * parsing started, this will return the complete document as an OFXMLElement
 * with all children.
 *
 * \param builder The builder which built an OFXMLElement
 * \param elem The OFXMLElement the OFXMLElementBuilder built
 */
- (void)elementBuilder: (OFXMLElementBuilder*)builder
       didBuildElement: (OFXMLElement*)elem;
@end

/**
 * \brief A class implementing the OFXMLParserDelegate protocol that can build
 * OFXMLElements from the document parsed by the OFXMLParser.
 *
 * It can also be used to build OFXMLElements from parts of the document by
 * first parsing stuff using the OFXMLParser with another delegate and then
 * setting the OFXMLElementBuilder as delegate for the parser.
 */
@interface OFXMLElementBuilder: OFObject
{
	OFMutableArray *stack;
	OFObject <OFXMLElementBuilderDelegate> *delegate;
}

#ifdef OF_HAVE_PROPERTIES
@property (retain) OFObject <OFXMLElementBuilderDelegate> *delegate;
#endif

/**
 * \return A new, autoreleased OFXMLElementBuilder
 */
+ elementBuilder;

/**
 * \return The delegate for the OFXMLElementBuilder
 */
- (OFObject <OFXMLElementBuilderDelegate>*)delegate;

/**
 * Sets the delegate for the OFXMLElementBuilder.
 *
 * \param delegate The delegate for the OFXMLElementBuilder
 */
- (void)setDelegate: (OFObject <OFXMLElementBuilderDelegate>*)delegate;
@end

Added src/OFXMLElementBuilder.m version [eae2627930].







































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Copyright (c) 2008 - 2010
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. 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"

#import "OFXMLElementBuilder.h"
#import "OFXMLElement.h"
#import "OFXMLParser.h"
#import "OFMutableArray.h"
#import "OFAutoreleasePool.h"

@implementation OFXMLElementBuilder
+ elementBuilder
{
	return [[[self alloc] init] autorelease];
}

- init
{
	self = [super init];

	stack = [[OFMutableArray alloc] init];

	return self;
}

- (void)dealloc
{
	[stack release];
	[delegate release];

	[super dealloc];
}

- (OFObject <OFXMLElementBuilderDelegate>*)delegate
{
	return [[delegate retain] autorelease];
}

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

-    (void)parser: (OFXMLParser*)parser
  didStartElement: (OFString*)name
       withPrefix: (OFString*)prefix
	namespace: (OFString*)ns
       attributes: (OFArray*)attrs
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFXMLElement *elem;
	OFXMLAttribute **attrs_c;
	size_t i, attrs_cnt;
	IMP add_attr;

	elem = [OFXMLElement elementWithName: name
				   namespace: ns];

	attrs_c = [attrs cArray];
	attrs_cnt = [attrs count];
	add_attr = [elem methodForSelector: @selector(addAttribute:)];

	for (i = 0; i < attrs_cnt; i++) {
		add_attr(elem, @selector(addAttribute:), attrs_c[i]);

		if ([attrs_c[i] namespace] == nil &&
		    [[attrs_c[i] name] isEqual: @"xmlns"])
			[elem setDefaultNamespace: [attrs_c[i] stringValue]];
		else if ([[attrs_c[i] namespace]
		    isEqual: @"http://www.w3.org/2000/xmlns/"])
			[elem setPrefix: [attrs_c[i] name]
			   forNamespace: [attrs_c[i] stringValue]];
	}

	[[stack lastObject] addChild: elem];
	[stack addObject: elem];

	[pool release];
}

-  (void)parser: (OFXMLParser*)parser
  didEndElement: (OFString*)name
     withPrefix: (OFString*)prefix
      namespace: (OFString*)ns
{
	if ([stack count] == 1)
		[delegate elementBuilder: self
			 didBuildElement: [stack firstObject]];

	[stack removeNObjects: 1];
}

-    (void)parser: (OFXMLParser*)parser
  foundCharacters: (OFString*)str
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	[[stack lastObject]
	    addChild: [OFXMLElement elementWithCharacters: str]];
	[pool release];
}

- (void)parser: (OFXMLParser*)parser
    foundCDATA: (OFString*)cdata
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	[[stack lastObject] addChild: [OFXMLElement elementWithCDATA: cdata]];
	[pool release];
}

- (void)parser: (OFXMLParser*)parser
  foundComment: (OFString*)comment
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFXMLElement *last = [stack lastObject];

	[last addChild: [OFXMLElement elementWithComment: comment]];

	[pool release];
}
@end

Modified tests/Makefile from [d7331cc9cf] to [1dd77cb076].

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
include ../extra.mk

SUBDIRS = ${TESTPLUGIN}

PROG_NOINST = tests${PROG_SUFFIX}
SRCS = OFArrayTests.m		\
       OFDataArrayTests.m	\
       OFDictionaryTests.m	\
       OFFileTests.m		\
       OFListTests.m		\
       OFMD5HashTests.m		\
       OFNumberTests.m		\
       OFObjectTests.m		\
       ${OFPLUGINTESTS_M}	\
       OFSHA1HashTests.m	\
       OFStreamTests.m		\
       OFStringTests.m		\
       OFTCPSocketTests.m	\
       ${OFTHREADTESTS_M}	\
       OFXMLElementTests.m	\

       OFXMLParserTests.m	\
       ${PROPERTIESTESTS_M}	\
       TestsAppDelegate.m

IPHONE_USER = mobile
IPHONE_TMP = /tmp/objfw-test

.PHONY: run run-tests run-on-iphone
run: all





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







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
include ../extra.mk

SUBDIRS = ${TESTPLUGIN}

PROG_NOINST = tests${PROG_SUFFIX}
SRCS = OFArrayTests.m			\
       OFDataArrayTests.m		\
       OFDictionaryTests.m		\
       OFFileTests.m			\
       OFListTests.m			\
       OFMD5HashTests.m			\
       OFNumberTests.m			\
       OFObjectTests.m			\
       ${OFPLUGINTESTS_M}		\
       OFSHA1HashTests.m		\
       OFStreamTests.m			\
       OFStringTests.m			\
       OFTCPSocketTests.m		\
       ${OFTHREADTESTS_M}		\
       OFXMLElementTests.m		\
       OFXMLElementBuilderTests.m	\
       OFXMLParserTests.m		\
       ${PROPERTIESTESTS_M}		\
       TestsAppDelegate.m

IPHONE_USER = mobile
IPHONE_TMP = /tmp/objfw-test

.PHONY: run run-tests run-on-iphone
run: all

Added tests/OFXMLElementBuilderTests.m version [cd0adc4059].















































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * Copyright (c) 2008 - 2010
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. 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>
#include <assert.h>

#import "OFXMLElementBuilder.h"
#import "OFXMLParser.h"
#import "OFAutoreleasePool.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFXMLElementBuilder";
static OFXMLElement *elem = nil;

@implementation TestsAppDelegate (OFXMLElementBuilderTests)
- (void)elementBuilder: (OFXMLElementBuilder*)builder
       didBuildElement: (OFXMLElement*)elem_
{
	assert(elem == nil);
	elem = [elem_ retain];
}

- (void)XMLElementBuilderTests
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFXMLParser *p = [OFXMLParser parser];
	OFXMLElementBuilder *builder = [OFXMLElementBuilder elementBuilder];
	const char *str = "<foo>bar<![CDATA[f<oo]]>baz<qux/>"
	    " <qux xmlns:qux='urn:qux'><qux:bar/><x qux:y='z'/></qux>"
	    "</foo>";

	[p setDelegate: builder];
	[builder setDelegate: self];

	TEST(@"Building element from parsed XML",
	    R([p parseBuffer: str
		    withSize: strlen(str)]) &&
    	    elem != nil && !strcmp([[elem string] cString], str))


	[elem release];
	[pool drain];
}
@end

Modified tests/TestsAppDelegate.h from [2d4213ddaa] to [2f884ceb5c].

1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
/*
 * Copyright (c) 2008 - 2010
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. 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 "OFApplication.h"


#define TEST(test, cond)				\
	{						\
		[self outputTesting: test		\
			   inModule: module];		\
							\
		if (cond)				\












>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * Copyright (c) 2008 - 2010
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. 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 "OFApplication.h"
#import "OFXMLElementBuilder.h"

#define TEST(test, cond)				\
	{						\
		[self outputTesting: test		\
			   inModule: module];		\
							\
		if (cond)				\
127
128
129
130
131
132
133
134




135
136
- (void)threadTests;
@end

@interface TestsAppDelegate (OFXMLElementTests)
- (void)XMLElementTests;
@end

@interface TestsAppDelegate (OFXMLParserTests)




- (void)XMLParserTests;
@end







|
>
>
>
>


128
129
130
131
132
133
134
135
136
137
138
139
140
141
- (void)threadTests;
@end

@interface TestsAppDelegate (OFXMLElementTests)
- (void)XMLElementTests;
@end

@interface TestsAppDelegate (OFXMLElementBuilderTests)
- (void)XMLElementBuilderTests;
@end

@interface TestsAppDelegate (OFXMLParserTests) <OFXMLElementBuilderDelegate>
- (void)XMLParserTests;
@end

Modified tests/TestsAppDelegate.m from [3a8f0dc730] to [9f82cc5699].

89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
	[self streamTests];
	[self TCPSocketTests];
#ifdef OF_THREADS
	[self threadTests];
#endif
	[self XMLElementTests];
	[self XMLParserTests];

#ifdef OF_PLUGINS
	[self pluginTests];
#endif
#ifdef OF_HAVE_PROPERTIES
	[self propertiesTests];
#endif

	if (fails > 0)
		[OFApplication terminateWithStatus: fails];
}
@end







>











89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
	[self streamTests];
	[self TCPSocketTests];
#ifdef OF_THREADS
	[self threadTests];
#endif
	[self XMLElementTests];
	[self XMLParserTests];
	[self XMLElementBuilderTests];
#ifdef OF_PLUGINS
	[self pluginTests];
#endif
#ifdef OF_HAVE_PROPERTIES
	[self propertiesTests];
#endif

	if (fails > 0)
		[OFApplication terminateWithStatus: fails];
}
@end