0
|
1 |
"{ Package: 'stx:goodies/xmlsuite/xmlreaderimpl' }"
|
|
2 |
|
|
3 |
"{ NameSpace: XMLv2 }"
|
|
4 |
|
|
5 |
XMLReader subclass:#ExpatXMLReader
|
|
6 |
instanceVariableNames:'parser'
|
|
7 |
classVariableNames:''
|
|
8 |
poolDictionaries:''
|
|
9 |
category:'XML Suite-SAX2-XMLReaders'
|
|
10 |
!
|
|
11 |
|
|
12 |
!ExpatXMLReader primitiveDefinitions!
|
|
13 |
%{
|
|
14 |
|
|
15 |
/*
|
|
16 |
* includes, defines, structure definitions
|
|
17 |
* and typedefs come here.
|
|
18 |
*/
|
|
19 |
|
|
20 |
#include <stdio.h>
|
|
21 |
#include <expat.h>
|
|
22 |
|
|
23 |
#define CHUNK_SIZE 8192
|
|
24 |
|
|
25 |
|
|
26 |
#define EXPAT_DEBUG(args) printf("ExpatXMLReader [debug]") ; printf args
|
|
27 |
|
|
28 |
#define EXPAT_DEBUG(args)
|
|
29 |
|
|
30 |
#define EXPAT_DEBUG_ENTER EXPAT_DEBUG((" Entering %s\n",__PRETTY_FUNCTION__))
|
|
31 |
#define EXPAT_DEBUG_LEAVE EXPAT_DEBUG((" Leaving %s\n",__PRETTY_FUNCTION__))
|
|
32 |
|
|
33 |
/*
|
|
34 |
HACK for development. If you write thode functions in
|
|
35 |
"Primitive functions" field, functions are not fileouted
|
|
36 |
when you "accept" primitive method in browser, so
|
|
37 |
C compiler can't compile native code using those methods.
|
|
38 |
*/
|
|
39 |
struct {
|
|
40 |
OBJ* this_object;
|
|
41 |
} user_data;
|
|
42 |
|
|
43 |
|
|
44 |
static void XMLCALL
|
|
45 |
startElement(OBJ** readerPointer, char* nameStr, char** attributes) {
|
|
46 |
OBJ reader;
|
|
47 |
OBJ attArray = nil;
|
|
48 |
OBJ attName,attValue;
|
|
49 |
int i;
|
|
50 |
EXPAT_DEBUG_ENTER;
|
|
51 |
for ( i = 0; attributes[i]; i += 2 ); /* compute length of att array */
|
|
52 |
EXPAT_DEBUG((" Element tiplet is %s\n",nameStr));
|
|
53 |
EXPAT_DEBUG((" Number of attributes is %d\n",i));
|
|
54 |
if ( i > 0 ) { /* there are some attributes */
|
|
55 |
attArray = __ARRAY_NEW_INT(i);
|
|
56 |
__PROTECT__(attArray); /* protect array to be garbage collected */
|
|
57 |
EXPAT_DEBUG((" Attribute array allocated. Entering fill loop\n"));
|
|
58 |
for ( i = 0; attributes[i]; i += 2 ) {/* fill att array */
|
|
59 |
EXPAT_DEBUG((" Processing attribute %s value %s\n",attributes[i],attributes[i+1]));
|
|
60 |
attName = __MKSTRING(attributes[i]);
|
|
61 |
attValue = __MKSTRING(attributes[i+1]);
|
|
62 |
__ArrayInstPtr(attArray)->a_element[i] = attName;
|
|
63 |
__STORE(attArray,attName); /* string may be different memory space than array */
|
|
64 |
__ArrayInstPtr(attArray)->a_element[i+1] = attValue;
|
|
65 |
__STORE(attArray,attValue); /* string may be different memory space than array */
|
|
66 |
}
|
|
67 |
EXPAT_DEBUG((" Attribute array filled\n"));
|
|
68 |
__UNPROTECT__(attArray); /* unprotect */
|
|
69 |
}
|
|
70 |
__PROTECT__(attArray);
|
|
71 |
char* name = __MKSTRING(nameStr);
|
|
72 |
__UNPROTECT__(attArray);
|
|
73 |
reader = **readerPointer;
|
|
74 |
EXPAT_DEBUG((" Reader is at %x, sending #expatStartElement:attributes:\n",reader));
|
|
75 |
__SSEND2(reader, @symbol(expatStartElement:attributes:),0, name, attArray);
|
|
76 |
EXPAT_DEBUG_LEAVE;
|
|
77 |
}
|
|
78 |
|
|
79 |
static void XMLCALL
|
|
80 |
endElement(OBJ** readerPointer, char* nameStr) {
|
|
81 |
OBJ reader;
|
|
82 |
OBJ name;
|
|
83 |
EXPAT_DEBUG_ENTER;
|
|
84 |
name = __MKSTRING(nameStr);
|
|
85 |
reader = **readerPointer;
|
|
86 |
__SSEND1(reader, @symbol(expatEndElement:),0, name);
|
|
87 |
EXPAT_DEBUG_LEAVE;
|
|
88 |
}
|
|
89 |
|
|
90 |
static void XMLCALL
|
|
91 |
startNSPrefixMapping(OBJ** readerPointer, char* prefixStr, char* uriStr) {
|
|
92 |
OBJ reader = **readerPointer;
|
|
93 |
OBJ prefix;
|
|
94 |
OBJ uri;
|
|
95 |
EXPAT_DEBUG_ENTER;
|
|
96 |
prefix = __MKSTRING(prefixStr);
|
|
97 |
uri = __MKSTRING(uriStr);
|
|
98 |
reader = **readerPointer;
|
|
99 |
__SSEND2(reader, @symbol(expatStartPrefix:mappingTo:),0, uri, prefix);
|
|
100 |
EXPAT_DEBUG_LEAVE;
|
|
101 |
}
|
|
102 |
|
|
103 |
static void XMLCALL
|
|
104 |
endNSPrefixMapping(OBJ** readerPointer, char* prefixStr) {
|
|
105 |
OBJ reader;
|
|
106 |
OBJ prefix;
|
|
107 |
EXPAT_DEBUG_ENTER;
|
|
108 |
prefix = __MKSTRING(prefixStr);
|
|
109 |
reader = **readerPointer;
|
|
110 |
__SSEND1(reader, @symbol(expatEndPrefixMapping:),0, prefix);
|
|
111 |
EXPAT_DEBUG_LEAVE;
|
|
112 |
}
|
|
113 |
|
|
114 |
static void XMLCALL
|
|
115 |
xmlProlog(OBJ** readerPointer, char* verStr, char* encStr, int standInt) {
|
|
116 |
OBJ reader;
|
|
117 |
OBJ version;
|
|
118 |
OBJ encoding;
|
|
119 |
OBJ standalone;
|
|
120 |
EXPAT_DEBUG_ENTER;
|
|
121 |
if (verStr == NULL) {
|
|
122 |
version = __MKSTRING("1.0");
|
|
123 |
} else {
|
|
124 |
version = __MKSTRING(verStr);
|
|
125 |
}
|
|
126 |
if (encStr == NULL) {
|
|
127 |
encoding = nil;
|
|
128 |
} else {
|
|
129 |
encoding = __MKSTRING(encStr);
|
|
130 |
}
|
|
131 |
standalone = __MKINT(standInt);
|
|
132 |
|
|
133 |
reader = **readerPointer;
|
|
134 |
__SSEND3(reader, @symbol(expatPrologVersion:encoding:standalone:),
|
|
135 |
0, version, encoding, standalone);
|
|
136 |
EXPAT_DEBUG_LEAVE;
|
|
137 |
}
|
|
138 |
|
|
139 |
|
|
140 |
|
|
141 |
|
|
142 |
static void XMLCALL
|
|
143 |
characters(OBJ** readerPointer, char* charStr, int charLen) {
|
|
144 |
OBJ reader = **readerPointer;
|
|
145 |
OBJ chars;
|
|
146 |
EXPAT_DEBUG_ENTER;
|
|
147 |
chars = __MKSTRING_L(charStr,charLen);
|
|
148 |
reader = **readerPointer;
|
|
149 |
__SSEND1(reader, @symbol(expatCharacters:),0, chars);
|
|
150 |
EXPAT_DEBUG_LEAVE;
|
|
151 |
}
|
|
152 |
|
|
153 |
static void XMLCALL
|
|
154 |
startCDataSection(OBJ** readerPointer) {
|
|
155 |
EXPAT_DEBUG_ENTER;
|
|
156 |
OBJ reader = **readerPointer;
|
|
157 |
__SSEND1(reader, @symbol(expatInCDataSection:),0,true);
|
|
158 |
EXPAT_DEBUG_LEAVE;
|
|
159 |
}
|
|
160 |
|
|
161 |
static void XMLCALL
|
|
162 |
endCDataSection(OBJ** readerPointer) {
|
|
163 |
EXPAT_DEBUG_ENTER;
|
|
164 |
OBJ reader = **readerPointer;
|
|
165 |
__SSEND1(reader, @symbol(expatInCDataSection:),0,false);
|
|
166 |
EXPAT_DEBUG_LEAVE;
|
|
167 |
}
|
|
168 |
|
|
169 |
static void XMLCALL
|
|
170 |
errorOccuredWhenParsing(XML_Parser p) {
|
|
171 |
OBJ reader;
|
|
172 |
OBJ errorString;
|
|
173 |
EXPAT_DEBUG_ENTER;
|
|
174 |
errorString = __MKSTRING(XML_ErrorString(XML_GetErrorCode(p)));
|
|
175 |
reader = **(OBJ**)XML_GetUserData(p);
|
|
176 |
__SSEND4(reader, @symbol(expatParseError:code:line:column:), 0,
|
|
177 |
errorString,
|
|
178 |
_MKSMALLINT(XML_GetErrorCode(p)),
|
|
179 |
_MKSMALLINT(XML_GetCurrentLineNumber(p)),
|
|
180 |
_MKSMALLINT(XML_GetCurrentColumnNumber(p)));
|
|
181 |
EXPAT_DEBUG_LEAVE;
|
|
182 |
}
|
|
183 |
|
|
184 |
static void XMLCALL
|
|
185 |
processingInstruction(OBJ** readerPointer, char* targetStr, char* dataStr) {
|
|
186 |
OBJ reader;
|
|
187 |
OBJ target;
|
|
188 |
OBJ data;
|
|
189 |
EXPAT_DEBUG_ENTER;
|
|
190 |
target = __MKSTRING(targetStr);
|
|
191 |
data = __MKSTRING(dataStr);
|
|
192 |
reader = **readerPointer;
|
|
193 |
__SSEND2(reader, @symbol(expatPI:data:),0, target,data);
|
|
194 |
EXPAT_DEBUG_LEAVE;
|
|
195 |
}
|
|
196 |
|
|
197 |
static void XMLCALL
|
|
198 |
comment(OBJ** readerPointer, char* commentStr) {
|
|
199 |
OBJ reader;
|
|
200 |
OBJ comment;
|
|
201 |
EXPAT_DEBUG_ENTER;
|
|
202 |
comment = __MKSTRING(commentStr);
|
|
203 |
reader = **readerPointer;
|
|
204 |
__SSEND1(reader, @symbol(expatComment:),0, comment);
|
|
205 |
EXPAT_DEBUG_LEAVE;
|
|
206 |
}
|
|
207 |
|
|
208 |
|
|
209 |
%}
|
|
210 |
! !
|
|
211 |
|
|
212 |
!ExpatXMLReader primitiveVariables!
|
|
213 |
%{
|
|
214 |
|
|
215 |
/*
|
|
216 |
* any local C variables
|
|
217 |
* come here (please, define as static)
|
|
218 |
*/
|
|
219 |
|
|
220 |
|
|
221 |
|
|
222 |
%}
|
|
223 |
! !
|
|
224 |
|
|
225 |
|
|
226 |
!ExpatXMLReader class methodsFor:'testing'!
|
|
227 |
|
|
228 |
isAvailable
|
|
229 |
"
|
|
230 |
self isAvailable
|
|
231 |
"
|
|
232 |
|
|
233 |
^self perform:#primitiveIsAvailable ifNotUnderstood:[false]
|
|
234 |
|
|
235 |
"Created: / 29-10-2006 / 22:37:05 / janfrog"
|
|
236 |
"Modified: / 12-04-2007 / 21:31:39 / janfrog"
|
|
237 |
!
|
|
238 |
|
|
239 |
primitiveIsAvailable
|
|
240 |
|
|
241 |
%{
|
|
242 |
RETURN(true);
|
|
243 |
%}.
|
|
244 |
^false
|
|
245 |
|
|
246 |
"Created: / 09-02-2007 / 17:44:42 / janfrog"
|
|
247 |
! !
|
|
248 |
|
|
249 |
!ExpatXMLReader methodsFor:'SAX2 interface - Locator'!
|
|
250 |
|
|
251 |
getColumnNumber
|
|
252 |
"Superclass says that I am responsible to implement this method"
|
|
253 |
|
|
254 |
^self primitiveGetCurrentColumnNumber
|
|
255 |
|
|
256 |
"Created: / 19-05-2005 / 09:43:25 / masca"
|
|
257 |
!
|
|
258 |
|
|
259 |
getLineNumber
|
|
260 |
"Superclass says that I am responsible to implement this method"
|
|
261 |
|
|
262 |
^self primitiveGetCurrentLineNumber
|
|
263 |
|
|
264 |
"Created: / 19-05-2005 / 09:43:37 / masca"
|
|
265 |
! !
|
|
266 |
|
|
267 |
!ExpatXMLReader methodsFor:'expat events'!
|
|
268 |
|
|
269 |
expatCharacters:aString
|
|
270 |
|
|
271 |
| handler |
|
|
272 |
handler := self getContentHandler.
|
|
273 |
(inCDataSection and:[handler respondsTo:#cDataSection:])
|
|
274 |
ifTrue:[^handler cDataSection:aString].
|
|
275 |
|
|
276 |
(aString allSatisfy:[:char|char isXMLWhiteSpace])
|
|
277 |
ifTrue:[handler ignorableWhitespace:aString]
|
|
278 |
ifFalse:[handler characters:aString]
|
|
279 |
|
|
280 |
"Created: / 17-04-2005 / 09:06:07 / janfrog"
|
|
281 |
"Modified: / 28-12-2005 / 16:18:15 / janfrog"
|
|
282 |
!
|
|
283 |
|
|
284 |
expatComment:aString
|
|
285 |
|
|
286 |
| handler |
|
|
287 |
|
|
288 |
handler := self getContentHandler.
|
|
289 |
(handler respondsTo:#comment:)
|
|
290 |
ifTrue:[handler comment:aString]
|
|
291 |
|
|
292 |
"Created: / 17-04-2005 / 13:33:10 / janfrog"
|
|
293 |
"Modified: / 28-12-2005 / 16:18:00 / janfrog"
|
|
294 |
!
|
|
295 |
|
|
296 |
expatEndDocument
|
|
297 |
|
|
298 |
self getContentHandler endDocument
|
|
299 |
|
|
300 |
"Created: / 17-04-2005 / 09:32:14 / janfrog"
|
|
301 |
!
|
|
302 |
|
|
303 |
expatEndDocumentFragment
|
|
304 |
|
|
305 |
self getContentHandler endDocumentFragment
|
|
306 |
|
|
307 |
"Created: / 23-04-2005 / 14:16:39 / janfrog"
|
|
308 |
!
|
|
309 |
|
|
310 |
expatEndElement:name
|
|
311 |
"name = String"
|
|
312 |
|
|
313 |
|nodeName|
|
|
314 |
|
|
315 |
nodeName := self nodeNameFromExpatExpandedElementName:name.
|
|
316 |
self getContentHandler
|
|
317 |
endElement:nodeName localName
|
|
318 |
namespace:nodeName ns
|
|
319 |
prefix:nodeName prefix
|
|
320 |
|
|
321 |
"Created: / 16-04-2005 / 21:36:24 / janfrog"
|
|
322 |
"Modified: / 29-09-2006 / 10:24:59 / janfrog"
|
|
323 |
!
|
|
324 |
|
|
325 |
expatEndPrefixMapping:prefix
|
|
326 |
|
|
327 |
self getContentHandler endPrefixMapping:prefix
|
|
328 |
|
|
329 |
"Created: / 17-04-2005 / 08:48:23 / janfrog"
|
|
330 |
!
|
|
331 |
|
|
332 |
expatInCDataSection: aBoolean
|
|
333 |
|
|
334 |
inCDataSection := aBoolean
|
|
335 |
|
|
336 |
"Created: / 28-12-2005 / 13:49:31 / janfrog"
|
|
337 |
"Modified: / 28-12-2005 / 16:18:04 / janfrog"
|
|
338 |
!
|
|
339 |
|
|
340 |
expatPI:target data:data
|
|
341 |
|
|
342 |
self getContentHandler processingInstruction:target data:data.
|
|
343 |
|
|
344 |
"Created: / 17-04-2005 / 13:32:50 / janfrog"
|
|
345 |
!
|
|
346 |
|
|
347 |
expatParseError:msg code:code line:line column:column
|
|
348 |
|
|
349 |
| error |
|
|
350 |
|
|
351 |
error := SAXParseError new
|
|
352 |
errorString:'Parse error at line ',line printString,' col ',column printString,' #',code printString,': ',msg;
|
|
353 |
line:line;
|
|
354 |
col:column.
|
|
355 |
self primitiveFreeExpatParser.
|
|
356 |
self getErrorHandler fatalError:error.
|
|
357 |
|
|
358 |
"Created: / 17-04-2005 / 09:54:19 / janfrog"
|
|
359 |
"Modified: / 21-04-2005 / 19:41:59 / janfrog"
|
|
360 |
!
|
|
361 |
|
|
362 |
expatPrologVersion: vers encoding: enc standalone: stand
|
|
363 |
|
|
364 |
xmlVersion := vers.
|
|
365 |
xmlEncoding := enc.
|
|
366 |
standalone := stand == 1
|
|
367 |
|
|
368 |
"Created: / 28-12-2005 / 16:18:14 / janfrog"
|
|
369 |
!
|
|
370 |
|
|
371 |
expatStartDocument
|
|
372 |
|
|
373 |
self getContentHandler startDocument
|
|
374 |
|
|
375 |
"Created: / 17-04-2005 / 09:32:03 / janfrog"
|
|
376 |
!
|
|
377 |
|
|
378 |
expatStartDocumentFragment
|
|
379 |
|
|
380 |
self getContentHandler startDocumentFragment
|
|
381 |
|
|
382 |
"Created: / 23-04-2005 / 14:16:24 / janfrog"
|
|
383 |
!
|
|
384 |
|
|
385 |
expatStartElement:name attributes:attArray
|
|
386 |
"name = String
|
|
387 |
attArray = array of strings. could be nil -> no attributes"
|
|
388 |
|
|
389 |
|nodeName attributes|
|
|
390 |
|
|
391 |
nodeName := self nodeNameFromExpatExpandedElementName:name.
|
|
392 |
attributes := attArray
|
|
393 |
ifNil:[ Attributes empty ]
|
|
394 |
ifNotNil:[
|
|
395 |
self attributesFromExpatAttArray:attArray inScopeOfNodeName:nodeName
|
|
396 |
].
|
|
397 |
self getContentHandler
|
|
398 |
startElement:nodeName localName
|
|
399 |
namespace:nodeName ns
|
|
400 |
prefix:nodeName prefix
|
|
401 |
attributes:attributes
|
|
402 |
|
|
403 |
"Created: / 16-04-2005 / 21:36:33 / janfrog"
|
|
404 |
"Modified: / 29-09-2006 / 10:24:25 / janfrog"
|
|
405 |
!
|
|
406 |
|
|
407 |
expatStartPrefix:prefix mappingTo:uri
|
|
408 |
|
|
409 |
self getContentHandler startPrefix:prefix mappingTo:uri
|
|
410 |
|
|
411 |
"Created: / 17-04-2005 / 08:47:52 / janfrog"
|
|
412 |
! !
|
|
413 |
|
|
414 |
!ExpatXMLReader methodsFor:'expat primitives'!
|
|
415 |
|
|
416 |
primitiveChunkSize
|
|
417 |
"Return chunk size"
|
|
418 |
|
|
419 |
%{
|
|
420 |
RETURN(_MKSMALLINT(CHUNK_SIZE));
|
|
421 |
%}
|
|
422 |
|
|
423 |
"Created: / 21-04-2005 / 19:38:18 / janfrog"
|
|
424 |
!
|
|
425 |
|
|
426 |
primitiveCreateExpatParser
|
|
427 |
"Creates and initialize expat parser"
|
|
428 |
|
|
429 |
%{
|
|
430 |
XML_Parser p;
|
|
431 |
OBJ** data;
|
|
432 |
OBJ parserAddress;
|
|
433 |
p = XML_ParserCreateNS(NULL,'|');
|
|
434 |
if (p != NULL) {
|
|
435 |
data = (OBJ**)malloc(sizeof (OBJ**));
|
|
436 |
EXPAT_DEBUG((" Allocating data=0x%x\n", data));
|
|
437 |
*data = (OBJ*)malloc(sizeof (OBJ*));
|
|
438 |
EXPAT_DEBUG((" Allocating *data=0x%x\n", *data));
|
|
439 |
**data = self;
|
|
440 |
EXPAT_DEBUG((" Parser is **data=0x%x\n", **data));
|
|
441 |
XML_SetUserData(p,data);
|
|
442 |
__ADD_REFCELL(*data);
|
|
443 |
XML_SetElementHandler(p, startElement, endElement);
|
|
444 |
XML_SetStartNamespaceDeclHandler(p, startNSPrefixMapping);
|
|
445 |
XML_SetEndNamespaceDeclHandler(p, endNSPrefixMapping);
|
|
446 |
XML_SetCharacterDataHandler(p, characters);
|
|
447 |
XML_SetCommentHandler(p, comment);
|
|
448 |
XML_SetProcessingInstructionHandler(p, processingInstruction);
|
|
449 |
XML_SetStartCdataSectionHandler(p, startCDataSection);
|
|
450 |
XML_SetEndCdataSectionHandler(p, endCDataSection);
|
|
451 |
XML_SetXmlDeclHandler(p, xmlProlog);
|
|
452 |
XML_SetReturnNSTriplet(p,1);
|
|
453 |
|
|
454 |
/* Store parser into instance variable */
|
|
455 |
parserAddress = (__MKEXTERNALADDRESS(p));
|
|
456 |
__INST(parser) = parserAddress;
|
|
457 |
__STORE(self, parserAddress);
|
|
458 |
|
|
459 |
/* return */
|
|
460 |
RETURN(self)
|
|
461 |
}
|
|
462 |
%}.
|
|
463 |
SAXError raiseErrorString:'Cannot create expat parser'
|
|
464 |
|
|
465 |
"Created: / 21-04-2005 / 19:00:58 / janfrog"
|
|
466 |
"Modified: / 28-12-2005 / 16:18:15 / janfrog"
|
|
467 |
!
|
|
468 |
|
|
469 |
primitiveFreeExpatParser
|
|
470 |
"Frees previously created expat parser"
|
|
471 |
|
|
472 |
%{
|
|
473 |
OBJ** data;
|
|
474 |
XML_Parser p;
|
|
475 |
if (__isExternalAddress(__INST(parser))) {
|
|
476 |
p = __externalAddressVal(__INST(parser));
|
|
477 |
data = (OBJ**)XML_GetUserData(p);
|
|
478 |
__REMOVE_REFCELL(*data);
|
|
479 |
EXPAT_DEBUG((" Parser is **data=0x%x\n", **data));
|
|
480 |
EXPAT_DEBUG((" Freeing *data=0x%x\n", *data));
|
|
481 |
free(*data);
|
|
482 |
EXPAT_DEBUG((" Freeing data=0x%x\n", data));
|
|
483 |
free(data);
|
|
484 |
XML_ParserFree(p);
|
|
485 |
}
|
|
486 |
%}.
|
|
487 |
parser := nil.
|
|
488 |
|
|
489 |
"Created: / 21-04-2005 / 19:03:20 / janfrog"
|
|
490 |
"Modified: / 11-08-2005 / 21:49:24 / janfrog"
|
|
491 |
!
|
|
492 |
|
|
493 |
primitiveGetCurrentColumnNumber
|
|
494 |
"Frees previously created expat parser"
|
|
495 |
|
|
496 |
%{
|
|
497 |
OBJ** data;
|
|
498 |
XML_Parser p;
|
|
499 |
if (__isExternalAddress(__INST(parser))) {
|
|
500 |
p = __externalAddressVal(__INST(parser));
|
|
501 |
RETURN(_MKSMALLINT(XML_GetCurrentColumnNumber(p)));
|
|
502 |
}
|
|
503 |
%}.
|
|
504 |
^nil
|
|
505 |
|
|
506 |
"Created: / 02-05-2005 / 12:03:19 / janfrog"
|
|
507 |
"Modified: / 11-08-2005 / 21:31:33 / janfrog"
|
|
508 |
!
|
|
509 |
|
|
510 |
primitiveGetCurrentLineNumber
|
|
511 |
"Frees previously created expat parser"
|
|
512 |
|
|
513 |
%{
|
|
514 |
OBJ** data;
|
|
515 |
XML_Parser p;
|
|
516 |
if (__isExternalAddress(__INST(parser))) {
|
|
517 |
p = __externalAddressVal(__INST(parser));
|
|
518 |
RETURN(_MKSMALLINT(XML_GetCurrentLineNumber(p)));
|
|
519 |
}
|
|
520 |
%}.
|
|
521 |
^nil
|
|
522 |
|
|
523 |
"Created: / 02-05-2005 / 12:03:30 / janfrog"
|
|
524 |
"Modified: / 11-08-2005 / 21:31:54 / janfrog"
|
|
525 |
!
|
|
526 |
|
|
527 |
primitiveParseChunk:aByteArray len:anInteger
|
|
528 |
"Frees previously created expat parser"
|
|
529 |
|
|
530 |
%{
|
|
531 |
unsigned char* chunk;
|
|
532 |
int chunkLen = __intVal(anInteger);
|
|
533 |
XML_Parser p;
|
|
534 |
EXPAT_DEBUG((" In #primitiveParseChunk:#[...] len:%d\n",chunkLen));
|
|
535 |
if (__isExternalAddress(__INST(parser))) {
|
|
536 |
p = __externalAddressVal(__INST(parser));
|
|
537 |
}
|
|
538 |
if (__isByteArray(aByteArray)) {
|
|
539 |
chunk = __byteArrayVal(aByteArray);
|
|
540 |
if (
|
|
541 |
XML_Parse(p, chunk, chunkLen, 0)
|
|
542 |
== XML_STATUS_ERROR
|
|
543 |
) {
|
|
544 |
errorOccuredWhenParsing(p);
|
|
545 |
RETURN(false);
|
|
546 |
}
|
|
547 |
} else {
|
|
548 |
RETURN(false);
|
|
549 |
}
|
|
550 |
EXPAT_DEBUG((" ...finished\n"));
|
|
551 |
%}.
|
|
552 |
^true
|
|
553 |
|
|
554 |
"Created: / 21-04-2005 / 20:09:08 / janfrog"
|
|
555 |
"Modified: / 06-10-2006 / 13:08:55 / janfrog"
|
|
556 |
! !
|
|
557 |
|
|
558 |
!ExpatXMLReader methodsFor:'expat utilities'!
|
|
559 |
|
|
560 |
attributesFromExpatAttArray:anArray inScopeOfNodeName:ownerNodeName
|
|
561 |
|
|
562 |
| attributes nodeName att |
|
|
563 |
|
|
564 |
anArray isEmpty ifTrue:[^Attributes empty].
|
|
565 |
attributes := Attributes new.
|
|
566 |
|
|
567 |
anArray pairWiseDo:[:name :value |
|
|
568 |
nodeName := self
|
|
569 |
nodeNameFromExpatExpandedAttributeName:name
|
|
570 |
inScopeOfNodeName:ownerNodeName.
|
|
571 |
att := Attr named:nodeName value:value.
|
|
572 |
attributes add:att
|
|
573 |
].
|
|
574 |
^attributes
|
|
575 |
|
|
576 |
"Created: / 11-08-2005 / 22:08:47 / janfrog"
|
|
577 |
"Modified: / 29-09-2006 / 10:22:46 / janfrog"
|
|
578 |
!
|
|
579 |
|
|
580 |
nodeNameFromExpatExpandedAttributeName:expandedName inScopeOfNodeName:ownerNodeName
|
|
581 |
|
|
582 |
| a |
|
|
583 |
a := expandedName tokensBasedOn:$|.
|
|
584 |
|
|
585 |
^(a size = 1) ifTrue:[
|
|
586 |
NodeName new
|
|
587 |
prefix:ownerNodeName prefix;
|
|
588 |
ns:ownerNodeName ns;
|
|
589 |
localName:a first
|
|
590 |
] ifFalse:[
|
|
591 |
NodeName new
|
|
592 |
prefix:a third;
|
|
593 |
ns:a first;
|
|
594 |
localName:a second.
|
|
595 |
]
|
|
596 |
|
|
597 |
"Created: / 11-08-2005 / 22:08:47 / janfrog"
|
|
598 |
"Modified: / 29-09-2006 / 10:25:26 / janfrog"
|
|
599 |
!
|
|
600 |
|
|
601 |
nodeNameFromExpatExpandedElementName:expandedName
|
|
602 |
|
|
603 |
| a |
|
|
604 |
a := expandedName tokensBasedOn:$|.
|
|
605 |
|
|
606 |
(a size = 2) ifTrue:[
|
|
607 |
^NodeName new
|
|
608 |
prefix:'';
|
|
609 |
ns:a first;
|
|
610 |
localName:a second
|
|
611 |
].
|
|
612 |
(a size = 3) ifTrue:[
|
|
613 |
^NodeName new
|
|
614 |
prefix:a third;
|
|
615 |
ns:a first;
|
|
616 |
localName:a second
|
|
617 |
].
|
|
618 |
^NodeName new
|
|
619 |
prefix:'';
|
|
620 |
ns:'';
|
|
621 |
localName:expandedName
|
|
622 |
|
|
623 |
"Created: / 11-08-2005 / 22:08:47 / janfrog"
|
|
624 |
"Modified: / 06-10-2006 / 09:42:08 / janfrog"
|
|
625 |
! !
|
|
626 |
|
|
627 |
!ExpatXMLReader methodsFor:'initialization'!
|
|
628 |
|
|
629 |
initialize
|
|
630 |
|
|
631 |
super initialize.
|
|
632 |
inCDataSection := false.
|
|
633 |
|
|
634 |
"Created: / 28-12-2005 / 16:18:06 / janfrog"
|
|
635 |
! !
|
|
636 |
|
|
637 |
!ExpatXMLReader methodsFor:'parsing'!
|
|
638 |
|
|
639 |
parseFragmentStream:aStream
|
|
640 |
|
|
641 |
| chunk chunkSize bytesRead fragmentHeader fragmentFooter |
|
|
642 |
aStream isReadable ifFalse:[
|
|
643 |
self getErrorHandler fatalError:
|
|
644 |
(SAXError withMessage:'Stream is not readable')
|
|
645 |
].
|
|
646 |
chunk := ByteArray new:(chunkSize := self primitiveChunkSize).
|
|
647 |
fragmentHeader := '<?xml version="1.0" ?><fragment>' .
|
|
648 |
fragmentFooter := '</fragment>'.
|
|
649 |
self primitiveCreateExpatParser.
|
|
650 |
aStream binary.
|
|
651 |
self expatStartDocumentFragment.
|
|
652 |
(self primitiveParseChunk:fragmentHeader len:fragmentHeader size) ifFalse:[
|
|
653 |
self getErrorHandler fatalError:(SAXError withMessage:'Hmm...cannot parse').
|
|
654 |
self primitiveFreeExpatParser.
|
|
655 |
^self
|
|
656 |
].
|
|
657 |
[aStream atEnd] whileFalse:[
|
|
658 |
aStream readWait.
|
|
659 |
bytesRead := aStream nextBytes:chunkSize into:chunk.
|
|
660 |
(self primitiveParseChunk:chunk len:bytesRead) ifFalse:[
|
|
661 |
self getErrorHandler fatalError:(SAXError withMessage:'Hmm...cannot parse').
|
|
662 |
self primitiveFreeExpatParser.
|
|
663 |
^self
|
|
664 |
]
|
|
665 |
].
|
|
666 |
(self primitiveParseChunk:fragmentFooter len:fragmentFooter size) ifFalse:[
|
|
667 |
self getErrorHandler fatalError:(SAXError withMessage:'Hmm...cannot parse').
|
|
668 |
self primitiveFreeExpatParser.
|
|
669 |
^self
|
|
670 |
].
|
|
671 |
self expatEndDocumentFragment.
|
|
672 |
self primitiveFreeExpatParser.
|
|
673 |
|
|
674 |
"Created: / 23-04-2005 / 14:16:13 / janfrog"
|
|
675 |
!
|
|
676 |
|
|
677 |
parseStream:aStream
|
|
678 |
|
|
679 |
| chunk chunkSize bytesRead |
|
|
680 |
aStream isReadable ifFalse:[
|
|
681 |
self getErrorHandler fatalError:
|
|
682 |
(SAXError withMessage:'Stream is not readable')
|
|
683 |
].
|
|
684 |
chunk := ByteArray new:(chunkSize := self primitiveChunkSize).
|
|
685 |
self primitiveCreateExpatParser.
|
|
686 |
aStream binary.
|
|
687 |
self expatStartDocument.
|
|
688 |
[aStream atEnd] whileFalse:[
|
|
689 |
aStream readWait.
|
|
690 |
bytesRead := aStream nextBytes:chunkSize into:chunk.
|
|
691 |
(self primitiveParseChunk:chunk len:bytesRead) ifFalse:[
|
|
692 |
self getErrorHandler fatalError:(SAXError withMessage:'Hmm...cannot parse').
|
|
693 |
self primitiveFreeExpatParser.
|
|
694 |
]
|
|
695 |
].
|
|
696 |
self expatEndDocument.
|
|
697 |
self primitiveFreeExpatParser.
|
|
698 |
|
|
699 |
"Created: / 21-04-2005 / 19:37:05 / janfrog"
|
|
700 |
! !
|
|
701 |
|
|
702 |
!ExpatXMLReader class methodsFor:'documentation'!
|
|
703 |
|
|
704 |
version
|
|
705 |
^ '$Header: /opt/data/cvs/stx/goodies/xmlsuite/xmlreaderimpl/XMLv2__ExpatXMLReader.st,v 1.7 2007-04-12 20:16:00 vranyj1 Exp $'
|
|
706 |
! !
|