ObjFW  Diff

Differences From Artifact [fd1f10a22d]:

  • File src/OFXMLElementBuilder.m — part of check-in [e1e7ffa903] at 2011-09-22 23:25:42 on branch trunk — Exceptions are now autoreleased.

    This is safe as an "exception loop" can't happen, since if allocating
    an exception fails, it throws an OFAllocFailedException which is
    preallocated and can always be thrown.

    So, the worst case would be that an autorelease of an exception fails,
    triggering an OFOutOfMemoryException for which there is no memory,
    resulting in an OFAllocFailedException to be thrown. (user: js, size: 4648) [annotate] [blame] [check-ins using]

To Artifact [975d3652b4]:


16
17
18
19
20
21
22




23
24
25
26
27
28
29
30
31
32
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35







+
+
+
+


-








#include "config.h"

#define OF_XML_ELEMENT_BUILDER_M

#import "OFXMLElementBuilder.h"
#import "OFXMLElement.h"
#import "OFXMLAttribute.h"
#import "OFXMLCharacters.h"
#import "OFXMLCDATA.h"
#import "OFXMLComment.h"
#import "OFXMLParser.h"
#import "OFMutableArray.h"
#import "OFAutoreleasePool.h"

#import "OFMalformedXMLException.h"

#import "macros.h"

@implementation OFXMLElementBuilder
+ elementBuilder
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
132
133
134
135
136


137
138

139
140
141




142
143
144


145
146
147
148
149
150
151
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
187
188
189
190





191
192
193
194
195
196
197
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
132
133


134
135

136
137



138
139
140
141
142


143
144

145
146
147
148
149


150
151
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
187
188
189
190
191
192
193
194
195
196
197







-



-






-











-
+




-
-







-
+
+





-
-
+
-


+
+







-
-
+
+
-

+
-
-
-
+
+
+
+

-
-
+
+
-





-
-
+
+

-
+
-
-
+

-
-
+
+
-





-
-
+
+

-
+
-
-
+

-
-
+
+
-















+
+
+
+
+








-    (void)parser: (OFXMLParser*)parser
  didStartElement: (OFString*)name
       withPrefix: (OFString*)prefix
	namespace: (OFString*)ns
       attributes: (OFArray*)attributes
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFXMLElement *element;
	OFXMLAttribute **cArray;
	size_t i, count;
	IMP addAttribute;

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

	cArray = [attributes cArray];
	count = [attributes count];
	addAttribute = [element methodForSelector: @selector(addAttribute:)];

	for (i = 0; i < count; i++) {
		if ([cArray[i] namespace] == nil &&
		    [[cArray[i] name] isEqual: @"xmlns"])
			continue;

		if ([[cArray[i] namespace]
		    isEqual: @"http://www.w3.org/2000/xmlns/"])
			[element setPrefix: [cArray[i] name]
			      forNamespace: [cArray[i] stringValue]];

		addAttribute(element, @selector(addAttribute:), cArray[i]);
		[element addAttribute: cArray[i]];
	}

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

	[pool release];
}

-  (void)parser: (OFXMLParser*)parser
  didEndElement: (OFString*)name
     withPrefix: (OFString*)prefix
      namespace: (OFString*)ns
{
	if ([stack count] == 0) {
	switch ([stack count]) {
	case 0:
		[delegate elementBuilder: self
		    didNotExpectCloseTag: name
			      withPrefix: prefix
			       namespace: ns];
		return;
	}

	case 1:
	if ([stack count] == 1)
		[delegate elementBuilder: self
			 didBuildElement: [stack firstObject]];
		break;
	}

	[stack removeLastObject];
}

-    (void)parser: (OFXMLParser*)parser
  foundCharacters: (OFString*)characters
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFXMLElement *element =
	OFXMLCharacters *node;
	OFXMLElement *parent;
	    [OFXMLElement elementWithCharacters: characters];

	node = [OFXMLCharacters charactersWithString: characters];
	if ([stack count] == 0)
		[delegate elementBuilder: self
			 didBuildElement: element];
	parent = [stack lastObject];

	if (parent != nil)
		[parent addChild: node];
	else
		[[stack lastObject] addChild: element];

		[delegate   elementBuilder: self
		    didBuildParentlessNode: node];
	[pool release];
}

- (void)parser: (OFXMLParser*)parser
    foundCDATA: (OFString*)CDATA
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFXMLElement *element = [OFXMLElement elementWithCDATA: CDATA];
	OFXMLCDATA *node = [OFXMLCDATA CDATAWithString: CDATA];
	OFXMLElement *parent = [stack lastObject];

	if ([stack count] == 0)
	if (parent != nil)
		[delegate elementBuilder: self
			 didBuildElement: element];
		[parent addChild: node];
	else
		[[stack lastObject] addChild: element];

		[delegate   elementBuilder: self
		    didBuildParentlessNode: node];
	[pool release];
}

- (void)parser: (OFXMLParser*)parser
  foundComment: (OFString*)comment
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFXMLElement *element = [OFXMLElement elementWithComment: comment];
	OFXMLComment *node = [OFXMLComment commentWithString: comment];
	OFXMLElement *parent = [stack lastObject];

	if ([stack count] == 0)
	if (parent != nil)
		[delegate elementBuilder: self
			 didBuildElement: element];
		[parent addChild: node];
	else
		[[stack lastObject] addChild: element];

		[delegate   elementBuilder: self
		    didBuildParentlessNode: node];
	[pool release];
}

-	(OFString*)parser: (OFXMLParser*)parser
  foundUnknownEntityNamed: (OFString*)entity
{
	return [delegate elementBuilder: self
		foundUnknownEntityNamed: entity];
}
@end

@implementation OFObject (OFXMLElementBuilderDelegate)
- (void)elementBuilder: (OFXMLElementBuilder*)builder
       didBuildElement: (OFXMLElement*)elem
{
}

-   (void)elementBuilder: (OFXMLElementBuilder*)builder
  didBuildParentlessNode: (OFXMLNode*)node
{
}

- (void)elementBuilder: (OFXMLElementBuilder*)builder
  didNotExpectCloseTag: (OFString*)name
	    withPrefix: (OFString*)prefix
	     namespace: (OFString*)ns
{
	@throw [OFMalformedXMLException exceptionWithClass: [builder class]