more updates for libxml2 2.5.10
[TestXSLT.git] / XMLParserLibxml.m
1 //
2 //  XMLParserLibxml.m
3 //  TestXSLT
4 //
5 //  Created by Marc Liyanage on Sun Aug 04 2002.
6 //  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
7 //
8
9 #import "XMLParserLibxml.h"
10
11
12 @implementation XMLParserLibxml
13
14
15 - (id)init {
16
17         if (self = [super init]) {
18
19                 errorMessage = [[NSMutableString alloc] init];
20                 errorLine = 0;
21                 errorOccurred = NO;
22                 //xmlContext = malloc(sizeof(xmlParserCtxt));
23                 //bzero(xmlContext, sizeof(xmlParserCtxt));
24                 parsedXmlDoc = NULL;
25                 baseUri = NULL;
26                 
27         }
28         
29         return self;
30 }
31
32
33 - (xmlDocPtr)nativeDoc {
34
35         return parsedXmlDoc;
36         
37 }
38
39 - (void)dealloc {
40
41         [errorMessage release];
42         [baseUri release];
43
44         if (parsedXmlDoc) {
45                 xmlFreeDoc(parsedXmlDoc);
46 //              free(xmlContext);
47         }
48
49         
50 }
51
52
53
54
55 - (void)setErrorMessage:(NSString *)message {
56
57         [errorMessage setString:message];
58
59 }
60
61 - (int)errorLine {
62
63         return errorLine;
64
65 }
66
67 - (NSString *)errorMessage {
68
69         return errorMessage;
70
71 }
72
73
74 - (void)setErrorOccurred:(BOOL)flag {
75
76         errorOccurred = flag;
77         
78 }
79
80 - (void)appendErrorMessage:(NSString *)message {
81
82         if ([errorMessage length] > 0) {
83                 [errorMessage appendString:@"\n"];
84         }
85         [errorMessage appendString:[message substringWithRange:NSMakeRange(0, [message length] - 1)]];
86         [self setErrorOccurred:YES];
87
88 }
89
90 - (BOOL)errorOccurred {
91
92         return errorOccurred;
93
94 }
95
96
97 - (void)setError:(NSString *)message atLine:(int)line {
98
99         [self setErrorMessage:message];
100         errorLine = line;
101         [self setErrorOccurred:YES];
102         
103
104 }
105
106
107 - (void)clearError {
108
109         [errorMessage setString:@""];
110         [self setErrorOccurred:NO];
111         errorLine = 0;
112
113 }
114
115
116 void makeUnixLineFeeds(char *buffer) {
117
118         int i = 0;
119
120         while (buffer[i] != '\0') {
121
122                 if (buffer[i] == '\r') {
123                         if (buffer[i + 1] == '\n') {
124                                 i++;
125                         } else {
126                                 buffer[i] = '\n';
127                         }
128                 }
129                 i++;
130         }
131         
132 }
133
134
135 - (BOOL)checkWellFormedData:(NSData *)xmlCode {
136
137         /*
138         // fixme: using nsdata now, not null-terminated. maybe replace with expat.
139         return YES;
140         char *xmlString = (char *)[xmlCode bytes];
141         //const char *xmlString = [stringData bytes];
142         int error = 0;
143
144         makeUnixLineFeeds(xmlString);
145         
146         /*
147         NSData *stringData = [xmlCode dataUsingEncoding:NSUTF8StringEncoding];
148         NSData *stringData = [xmlCode dataUsingEncoding:NSISOLatin1StringEncoding];
149
150
151          xmlString = malloc([stringData length] + 1);
152         [stringData getBytes:xmlString];
153         xmlString[[stringData length]] = '\0';
154          */
155                 
156
157 //      xmlContext = xmlCreateDocParserCtxt(xmlString);
158         /*
159         if (!xmlContext) {
160                 return NO;
161         }
162
163
164         [self clearError];
165         xmlSetGenericErrorFunc(self, (xmlGenericErrorFunc)XMLParserLibxml_xmlErrorHandler);
166
167         error = xmlParseDocument(xmlContext);
168
169         if (xmlContext->myDoc) {
170                 xmlFreeDoc(xmlContext->myDoc);
171         }
172
173         xmlFreeParserCtxt(xmlContext);
174         xmlContext = NULL;
175
176         if (error != XML_ERR_OK) {
177                 return NO;
178         } else {
179                 [self clearError];
180                 return YES;
181         }
182
183 */
184          
185 }
186
187
188
189
190 - (BOOL)parseData:(NSData *)xmlCode {
191
192         int error = 0;
193
194 //      makeUnixLineFeeds(xmlString);
195
196     xmlSubstituteEntitiesDefault(1);
197         xmlLoadExtDtdDefaultValue = 1;
198
199         [self clearError];
200         xmlSetGenericErrorFunc(self, (xmlGenericErrorFunc)XMLParserLibxml_xmlErrorHandler);
201
202         if (parsedXmlDoc) {
203                 xmlFreeDoc(parsedXmlDoc);
204         }
205         
206         parsedXmlDoc = xmlParseMemory([xmlCode bytes], [xmlCode length]);
207
208         if (!parsedXmlDoc) {
209                 return NO;
210         }
211         
212         if ([self baseUri] != nil) {
213                 xmlNodeSetBase((xmlNodePtr)parsedXmlDoc, (xmlChar *)[[self baseUri] cString]);
214         }
215         [self clearError];
216         return YES;
217
218                 
219 }
220
221
222
223 - (void)markFirstErrorLine {
224
225 //      if (errorLine == 0 && xmlContext && xmlContext->input) {
226 //              errorLine = xmlContext->input->line;
227 //      }
228
229         
230 }
231
232 void XMLParserLibxml_xmlErrorHandler(id self, const char *message, ...) {
233
234         char *messageData;
235         va_list args;
236
237
238         
239         [self markFirstErrorLine];
240
241         /* we're only interested in messages with the format string "%s" */
242         if (strcmp(message, "%s")) {
243                 return;
244         }
245
246         va_start(args, message);
247         messageData = va_arg(args, char *);
248
249         [self appendErrorMessage:[NSString stringWithCString:messageData]];
250
251     va_end(args);
252
253
254 }
255
256
257 void XMLParserLibxml_xmlErrorHandler2(id self, const char *message, ...) {
258
259         const char *end = message + (strlen(message) - 1);
260         char *pos = (char *)message;
261         int errorLine = 0;
262         NSString *errorMessage;
263         char completeMessage[512];
264         va_list args;
265
266         /*      Do not overwrite previous error information so the
267                 first error in a series will be preserved
268                 */
269         if ([self errorOccurred]) {
270                 return;
271         }
272
273 //      NSLog(@"xml error handler: %s", message);
274
275         va_start(args, message);
276
277         while (pos <= end) {
278
279                 if (!strncmp(pos, "%s", 2)) {
280                         va_arg(args, char *);
281                 } else if (!strncmp(pos, "%d", 2)) {
282                         errorLine = va_arg(args, int);
283                 }
284
285                 pos++;
286
287         }
288
289     va_end(args);
290
291         va_start(args, message);
292         vsnprintf(completeMessage, 512, message, args);
293     va_end(args);
294
295         errorMessage = [NSString stringWithCString:completeMessage];
296         [self setError:errorMessage atLine:errorLine];
297
298
299 }
300
301
302 - (void)setBaseUri:(NSString *)uri {
303
304         [uri retain];
305         [baseUri release];
306         baseUri = uri;
307 }
308
309 - (NSString *)baseUri {
310         return baseUri;
311 }
312
313
314
315 @end