1 /* |
|
2 * Copyright (c) 2000 - 2001 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "cxml_internal.h" |
|
19 #include <xml/cxml/nw_xmlp_xmlreader.h> |
|
20 #include <xml/cxml/nw_xmlp_xmlparser.h> |
|
21 #include <xml/cxml/nw_encoder_wbxmlwriter.h> |
|
22 |
|
23 |
|
24 #include "cxml_xmlp_entity.h" |
|
25 #include <xml/cxml/nw_string_string.h> |
|
26 #include "cxml_xmlp_int_entity.h" |
|
27 |
|
28 |
|
29 |
|
30 /* "<?" len 2 */ |
|
31 #define NW_XML_String_PiFormStartLength 2 |
|
32 static |
|
33 const NW_Uint8 NW_XML_String_PiFormStart[NW_XML_String_PiFormStartLength] = |
|
34 { |
|
35 '<', '?' |
|
36 }; |
|
37 |
|
38 /* "?>" len 2 */ |
|
39 #define NW_XML_String_PiFormStopLength 2 |
|
40 static |
|
41 const NW_Uint8 NW_XML_String_PiFormStop[NW_XML_String_PiFormStopLength] = |
|
42 { |
|
43 '?', '>' |
|
44 }; |
|
45 |
|
46 /* "version" len 7 */ |
|
47 #define NW_XML_String_VersionLength 7 |
|
48 static |
|
49 const NW_Uint8 NW_XML_String_Version[NW_XML_String_VersionLength] = |
|
50 { |
|
51 'v', 'e', 'r', 's', 'i', 'o', 'n' |
|
52 }; |
|
53 |
|
54 /* "encoding" len 8 */ |
|
55 #define NW_XML_String_EncodingLength 8 |
|
56 static |
|
57 const NW_Uint8 NW_XML_String_Encoding[NW_XML_String_EncodingLength] = |
|
58 { |
|
59 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g' |
|
60 }; |
|
61 |
|
62 /* "standalone" len 10 */ |
|
63 #define NW_XML_String_StandaloneLength 10 |
|
64 static |
|
65 const NW_Uint8 NW_XML_String_Standalone[NW_XML_String_StandaloneLength] = |
|
66 { |
|
67 's', 't', 'a', 'n', 'd', 'a', 'l', 'o', 'n', 'e' |
|
68 }; |
|
69 |
|
70 /* "<!DOCTYPE" len 9 */ |
|
71 #define NW_XML_String_DoctypeStartLength 9 |
|
72 static |
|
73 const NW_Uint8 NW_XML_String_DoctypeStart[NW_XML_String_DoctypeStartLength] = |
|
74 { |
|
75 '<', '!', 'D', 'O', 'C', 'T', 'Y', 'P', 'E' |
|
76 }; |
|
77 |
|
78 /* "<!ENTITY" len 8 in the DTD */ |
|
79 |
|
80 #define NW_XML_String_EntityStartLength 8 |
|
81 static |
|
82 const NW_Uint8 NW_XML_String_EntityStart[NW_XML_String_EntityStartLength] = |
|
83 { |
|
84 '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y' |
|
85 }; |
|
86 |
|
87 /* "<!--" len 4 comment start */ |
|
88 #define NW_XML_String_CommentStartLength 4 |
|
89 static |
|
90 const NW_Uint8 NW_XML_String_CommentStart[NW_XML_String_CommentStartLength] = |
|
91 { |
|
92 '<', '!', '-', '-' |
|
93 }; |
|
94 |
|
95 /* "-->" len 3 comment end */ |
|
96 #define NW_XML_String_CommentStopLength 3 |
|
97 static |
|
98 const NW_Uint8 NW_XML_String_CommentStop[NW_XML_String_CommentStopLength] = |
|
99 { |
|
100 '-', '-', '>' |
|
101 }; |
|
102 |
|
103 /* "/>" len 2 */ |
|
104 #define NW_XML_String_EmptyTagEndLength 2 |
|
105 static |
|
106 const NW_Uint8 NW_XML_String_EmptyTagEnd[NW_XML_String_EmptyTagEndLength] = |
|
107 { |
|
108 '/', '>' |
|
109 }; |
|
110 |
|
111 /* "</" len 2 */ |
|
112 #define NW_XML_String_EndTagStartLength 2 |
|
113 static |
|
114 const NW_Uint8 NW_XML_String_EndTagStart[NW_XML_String_EndTagStartLength] = |
|
115 { |
|
116 '<', '/' |
|
117 }; |
|
118 |
|
119 /* "<![CDATA[" len 9 */ |
|
120 #define NW_XML_String_CdataStartLength 9 |
|
121 static |
|
122 const NW_Uint8 NW_XML_String_CdataStart[NW_XML_String_CdataStartLength] = |
|
123 { |
|
124 '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[' |
|
125 }; |
|
126 |
|
127 /* "]]>" len 3 */ |
|
128 #define NW_XML_String_CdataEndLength 3 |
|
129 static |
|
130 const NW_Uint8 NW_XML_String_CdataEnd[NW_XML_String_CdataEndLength] = |
|
131 { |
|
132 ']', ']', '>' |
|
133 }; |
|
134 |
|
135 /* All case variations of "xml" */ |
|
136 #define NW_XML_String_XmlNameVariationCount 8 |
|
137 #define NW_XML_String_XmlLength 3 |
|
138 static |
|
139 const NW_Uint8 NW_XML_String_XmlVariations[(NW_XML_String_XmlNameVariationCount |
|
140 * NW_XML_String_XmlLength)] = |
|
141 { |
|
142 'x', 'm', 'l', /* all lower case form must be first */ |
|
143 'x', 'm', 'L', |
|
144 'x', 'M', 'l', |
|
145 'x', 'M', 'L', |
|
146 'X', 'm', 'l', |
|
147 'X', 'm', 'L', |
|
148 'X', 'M', 'l', |
|
149 'X', 'M', 'L' |
|
150 }; |
|
151 |
|
152 |
|
153 /* Assumes position in Reader is at the first character of keyword. |
|
154 returns: *pMatch = 1 if found keyword and advanced over it, 0 if no match |
|
155 NOTE: Keyword match just means the string of keyword chars |
|
156 exists at the read position so it does not mean that the keyword |
|
157 is delimited at the end---it might be followed by more name chars. */ |
|
158 static |
|
159 NW_Status_t |
|
160 NW_XML_Parse_KeywordConsume(NW_XML_Reader_t* pT, NW_XML_Reader_Interval_t* pI, |
|
161 NW_Uint32 l, const NW_Uint8* pKeyword, |
|
162 NW_Uint32* pMatch) |
|
163 { |
|
164 NW_Status_t s; |
|
165 NW_XML_Reader_Interval_Init(pI); |
|
166 s = NW_XML_Reader_AsciiStringMatch(pT, l, pKeyword, pMatch); |
|
167 if (NW_STAT_IS_SUCCESS(s) && *pMatch) { |
|
168 NW_XML_Reader_Interval_Start(pI, pT); |
|
169 NW_XML_Reader_AdvanceOffset(pT, l); |
|
170 NW_XML_Reader_Interval_Stop(pI, pT); |
|
171 } |
|
172 return s; |
|
173 } |
|
174 |
|
175 /* |
|
176 Parses an XML Name (productions 5, 4) in Reader. |
|
177 If no parse error, then *pI marks the Name. |
|
178 Assumes position in Reader is at the first character of name. |
|
179 returns: *pMatch = 1 if found name and advanced over it, 0 if no match |
|
180 */ |
|
181 static |
|
182 NW_Status_t |
|
183 NW_XML_Parse_NameConsume(NW_XML_Reader_t* pT, NW_XML_Reader_Interval_t* pI, |
|
184 NW_Uint32* pMatch) |
|
185 { |
|
186 /* |
|
187 [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
|
188 | CombiningChar | Extender |
|
189 |
|
190 Note: combining and extender ignored here. |
|
191 |
|
192 [5] Name ::= (Letter | '_' | ':') (NameChar)* |
|
193 */ |
|
194 NW_Status_t sl; |
|
195 NW_Uint32 isLetter; |
|
196 NW_Status_t su; |
|
197 NW_Uint32 isUnderscore; |
|
198 NW_Status_t sc; |
|
199 NW_Uint32 isColon; |
|
200 NW_Status_t sd = NW_STAT_SUCCESS; |
|
201 NW_Uint32 isDigit = 0; |
|
202 NW_Status_t sp = NW_STAT_SUCCESS; |
|
203 NW_Uint32 isPeriod = 0; |
|
204 NW_Status_t sh = NW_STAT_SUCCESS; |
|
205 NW_Uint32 isHyphen = 0; |
|
206 NW_Status_t s = NW_STAT_SUCCESS; |
|
207 |
|
208 sl = NW_XML_Reader_IsLetter(pT, &isLetter); |
|
209 su = NW_XML_Reader_AsciiCharMatch(pT, '_', &isUnderscore); |
|
210 sc = NW_XML_Reader_AsciiCharMatch(pT, ':', &isColon); |
|
211 *pMatch = 0; |
|
212 NW_XML_Reader_Interval_Init(pI); |
|
213 if (NW_STAT_IS_SUCCESS(sl) && NW_STAT_IS_SUCCESS(su) |
|
214 && NW_STAT_IS_SUCCESS(sc)) { |
|
215 if (isLetter | isUnderscore | isColon) { |
|
216 NW_XML_Reader_Interval_Start(pI, pT); |
|
217 while ((NW_STAT_IS_SUCCESS(sl) && NW_STAT_IS_SUCCESS(su) |
|
218 && NW_STAT_IS_SUCCESS(sc) && NW_STAT_IS_SUCCESS(sd) |
|
219 && NW_STAT_IS_SUCCESS(sp) && NW_STAT_IS_SUCCESS(sh) |
|
220 && NW_STAT_IS_SUCCESS(s)) |
|
221 && (isLetter | isDigit | isPeriod | isHyphen | isUnderscore |
|
222 | isColon )) { |
|
223 s = NW_XML_Reader_Advance(pT); |
|
224 sl = NW_XML_Reader_IsLetter(pT, &isLetter); |
|
225 sd = NW_XML_Reader_IsDigit(pT, &isDigit); |
|
226 sp = NW_XML_Reader_AsciiCharMatch(pT, '.', &isPeriod); |
|
227 sh = NW_XML_Reader_AsciiCharMatch(pT, '-', &isHyphen); |
|
228 su = NW_XML_Reader_AsciiCharMatch(pT, '_', &isUnderscore); |
|
229 sc = NW_XML_Reader_AsciiCharMatch(pT, ':', &isColon); |
|
230 } |
|
231 NW_XML_Reader_Interval_Stop(pI, pT); |
|
232 *pMatch = 1; |
|
233 } |
|
234 } |
|
235 if (NW_STAT_IS_SUCCESS(sl) && NW_STAT_IS_SUCCESS(su) |
|
236 && NW_STAT_IS_SUCCESS(sc) && NW_STAT_IS_SUCCESS(sd) |
|
237 && NW_STAT_IS_SUCCESS(sp) && NW_STAT_IS_SUCCESS(sh) |
|
238 && NW_STAT_IS_SUCCESS(s)) { |
|
239 return NW_STAT_SUCCESS; |
|
240 } |
|
241 return NW_STAT_FAILURE; |
|
242 } |
|
243 |
|
244 /* This function reads data from the pT->pBuf and converts this data to |
|
245 * the NW_String_t. The string memory is allocated here but it is freed |
|
246 * in the calling function. |
|
247 * |
|
248 * pT --> Parser Structute (IN) |
|
249 * I_attrVal --> Attribute value Interval parameter (IN) |
|
250 * *dataStr --> Output string (OUT) |
|
251 * |
|
252 * |
|
253 */ |
|
254 |
|
255 static NW_Status_t NW_XML_Data_to_String(NW_XML_Reader_t* pT, NW_XML_Reader_Interval_t* I_attrVal, |
|
256 NW_String_t* dataStr) |
|
257 { |
|
258 NW_Uint8* pData; |
|
259 NW_Uint32 numbytes = 0; |
|
260 NW_Uint32 totalByteCount = 0; |
|
261 CXML_Uint8* tempAttrValBuf; |
|
262 CXML_Uint32 tempBufLen = 0; |
|
263 NW_Uint32 length; |
|
264 NW_Uint32 i =0; |
|
265 NW_Ucs2 c; |
|
266 NW_Status_t s; |
|
267 |
|
268 length = I_attrVal->stop - I_attrVal->start; |
|
269 tempBufLen = length; //Desired bytes need to read. |
|
270 |
|
271 s = NW_XML_Reader_DataAddressFromBuffer(pT,I_attrVal->start, |
|
272 &tempBufLen, |
|
273 &tempAttrValBuf); |
|
274 |
|
275 if (NW_STAT_IS_FAILURE(s)) |
|
276 { |
|
277 return s; |
|
278 } |
|
279 |
|
280 if (tempBufLen != length) |
|
281 { |
|
282 return NW_STAT_FAILURE; |
|
283 } |
|
284 |
|
285 |
|
286 |
|
287 /* pData is not NULL terminated so need to use following method. The num byte |
|
288 * will be used for both pName and pVlaue. |
|
289 */ |
|
290 |
|
291 |
|
292 numbytes = NW_String_readChar( (NW_Byte*) tempAttrValBuf,&c,pT->encoding); |
|
293 |
|
294 /* Calculate the length of string. Also add the number of characters |
|
295 * required for the NULL termination. |
|
296 */ |
|
297 |
|
298 totalByteCount = length + numbytes; |
|
299 |
|
300 pData = (NW_Uint8*) NW_Mem_Malloc(totalByteCount); |
|
301 |
|
302 if (pData != NULL) |
|
303 { |
|
304 (void)NW_Mem_memcpy(pData , tempAttrValBuf, length ); |
|
305 |
|
306 |
|
307 for(i=0; i < numbytes; i++) |
|
308 { |
|
309 pData[length+i] = '\0'; |
|
310 } |
|
311 } /*end if (pName != NULL)*/ |
|
312 else |
|
313 { |
|
314 return NW_STAT_OUT_OF_MEMORY; |
|
315 } |
|
316 |
|
317 s = NW_String_initialize( dataStr , pData, pT->encoding); |
|
318 |
|
319 if (NW_STAT_IS_FAILURE(s)) |
|
320 { |
|
321 return s; |
|
322 } |
|
323 |
|
324 /* This will the storage of the dataStr by the NW_String_delete() */ |
|
325 |
|
326 dataStr->length |= 0x80000000; |
|
327 |
|
328 return NW_STAT_SUCCESS; |
|
329 |
|
330 }/*end NW_XML_Data_to_String()*/ |
|
331 |
|
332 /* Assumes position in Reader is at the opening quote character for value. |
|
333 * BUG not yet spec compliant. |
|
334 * The following function is called for Process Instruction and Element |
|
335 * attribute consume. The predefined entities will be handled in |
|
336 * element attributes only. So, the "entity" parameter is used to |
|
337 * distinguish between these two cases. |
|
338 * Careful about the "entity" parameter passed. This is used both as |
|
339 * IN/OUT paramter. |
|
340 |
|
341 * IN --> if(entity == CXML_TRUE): Then parse attribute value for the |
|
342 * entities. |
|
343 |
|
344 * OUT --> (entity=CXML_TRUE): The entity is found in the attribute value. |
|
345 |
|
346 */ |
|
347 |
|
348 static |
|
349 NW_Status_t |
|
350 NW_XML_Parse_ValueConsume(NW_XML_Reader_t* pT, NW_XML_Reader_Interval_t* pI, |
|
351 CXML_Bool* entityCheck, NW_String_t* attrValStr, |
|
352 const RPointerArray <CXML_Internal_Entity_t>* internalEntityList) |
|
353 { |
|
354 /* |
|
355 Literal data is any quoted string not containing the quotation mark |
|
356 used as a delimiter for that string. |
|
357 |
|
358 [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
|
359 | "'" ([^<&'] | Reference)* "'" |
|
360 */ |
|
361 |
|
362 /* BUG this only pays attention to the quote chars not the value |
|
363 so it ignores [<&]. */ |
|
364 NW_Status_t s; |
|
365 NW_Status_t ssq; |
|
366 NW_Uint32 isOpenSingleQuote; |
|
367 NW_Uint32 isCloseSingleQuote = 0; |
|
368 NW_Status_t sdq; |
|
369 NW_Uint32 isOpenDoubleQuote; |
|
370 NW_Uint32 isCloseDoubleQuote = 0; |
|
371 NW_Status_t slt; |
|
372 NW_Uint32 isLessThan; |
|
373 |
|
374 NW_Uint32 prevIndex; |
|
375 NW_Uint32 prevCharIndex; |
|
376 NW_XML_Reader_LineColumn_t prevLineColumn; |
|
377 CXML_Uint8* intEntityValStr = NULL; |
|
378 CXML_Uint32 tempBufLen = 0; |
|
379 NW_String_t* tempStr = NULL; |
|
380 NW_String_t entityValStr; |
|
381 CXML_Bool entityFoundLevel_2 = NW_FALSE; |
|
382 CXML_Bool entityFoundOnce = NW_FALSE; |
|
383 NW_String_initialize (&entityValStr, NULL, 0); |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 NW_XML_Reader_Interval_Init(pI); |
|
389 ssq = NW_XML_Reader_AsciiCharMatch(pT, '\'', &isOpenSingleQuote); |
|
390 sdq = NW_XML_Reader_AsciiCharMatch(pT, '\"', &isOpenDoubleQuote); |
|
391 if (NW_STAT_IS_FAILURE(sdq) || NW_STAT_IS_FAILURE(ssq) |
|
392 || (!isOpenSingleQuote && !isOpenDoubleQuote)) { |
|
393 return NW_STAT_FAILURE; |
|
394 } |
|
395 /* xor, mutually exclusive */ |
|
396 NW_ASSERT(isOpenSingleQuote ^ isOpenDoubleQuote); |
|
397 s = NW_XML_Reader_Advance(pT); |
|
398 if (NW_STAT_IS_FAILURE(s)) { |
|
399 return NW_STAT_FAILURE; |
|
400 } |
|
401 NW_XML_Reader_Interval_Start(pI, pT); |
|
402 for (;;) { |
|
403 |
|
404 /* Check for the closing quotes. If this is empty attribute value |
|
405 * then no need for the checking the entities. |
|
406 */ |
|
407 |
|
408 if (isOpenSingleQuote) { |
|
409 ssq = NW_XML_Reader_AsciiCharMatch(pT, '\'', &isCloseSingleQuote); |
|
410 } |
|
411 if (isOpenDoubleQuote) { |
|
412 sdq = NW_XML_Reader_AsciiCharMatch(pT, '\"', &isCloseDoubleQuote); |
|
413 } |
|
414 slt = NW_XML_Reader_AsciiCharMatch(pT, '<', &isLessThan); |
|
415 if (NW_STAT_IS_FAILURE(ssq) || NW_STAT_IS_FAILURE(sdq) |
|
416 || NW_STAT_IS_FAILURE(slt) || isLessThan) { |
|
417 return NW_STAT_FAILURE; |
|
418 } |
|
419 |
|
420 |
|
421 if( (*entityCheck == CXML_TRUE) && !isCloseSingleQuote && !isCloseDoubleQuote) |
|
422 { |
|
423 NW_Uint32 match; |
|
424 |
|
425 s = NW_XML_Reader_AsciiCharMatch(pT, '&', &match); |
|
426 |
|
427 if (NW_STAT_IS_FAILURE(s)) |
|
428 { |
|
429 return NW_STAT_FAILURE; |
|
430 } |
|
431 if (match) |
|
432 { |
|
433 NW_XML_Reader_Interval_t I_entityData; |
|
434 NW_Bool entityFoundLevel_1 = NW_FALSE; //If end of entity (;) found |
|
435 NW_Uint32 entityVal = 0; |
|
436 NW_XML_Reader_Interval_t* I_attrVal = pI; |
|
437 |
|
438 |
|
439 |
|
440 entityFoundLevel_2 = NW_FALSE; |
|
441 NW_XML_Reader_Interval_Stop(I_attrVal, pT); //Contents before entity |
|
442 |
|
443 //Will back if not a valid entity |
|
444 NW_XML_Reader_GetPosition(pT, |
|
445 &prevIndex, &prevCharIndex, &prevLineColumn); |
|
446 |
|
447 s = CXML_XML_Parser_Entity(pT,&I_entityData,&entityFoundLevel_1); |
|
448 |
|
449 if (NW_STAT_IS_FAILURE(s)) |
|
450 { |
|
451 return NW_STAT_FAILURE; |
|
452 } |
|
453 /* |
|
454 if(entityFoundLevel_1 == NW_FALSE) |
|
455 { |
|
456 return NW_STAT_XHTML_BAD_CONTENT; |
|
457 } |
|
458 */ |
|
459 if (entityFoundLevel_1) |
|
460 { |
|
461 // Validate the entity |
|
462 // The following function checks for the character, |
|
463 // predefined and Internal Entities. |
|
464 |
|
465 if( (I_entityData.stop - I_entityData.start) > 0) |
|
466 { |
|
467 s = CXML_XML_Handle_entity(pT, |
|
468 &I_entityData,&entityVal,&intEntityValStr, |
|
469 &entityFoundLevel_2, |
|
470 (void*) internalEntityList); |
|
471 } |
|
472 else |
|
473 { |
|
474 //Not a valid entity e.g. "&&;" test case |
|
475 entityFoundLevel_2 = NW_FALSE; |
|
476 } |
|
477 |
|
478 if (NW_STAT_IS_FAILURE(s)) |
|
479 { |
|
480 return NW_STAT_FAILURE; |
|
481 } |
|
482 |
|
483 if(entityFoundLevel_2 == CXML_TRUE) |
|
484 { |
|
485 /* Read contents before entity*/ |
|
486 |
|
487 tempBufLen = I_attrVal->stop - I_attrVal->start; |
|
488 |
|
489 if(tempBufLen > 0) |
|
490 { |
|
491 |
|
492 if(tempStr == NULL) |
|
493 { |
|
494 tempStr = NW_String_new(); |
|
495 if(tempStr == NULL) |
|
496 { |
|
497 return NW_STAT_OUT_OF_MEMORY; |
|
498 } |
|
499 |
|
500 } /*end if(tempStr == NULL)*/ |
|
501 |
|
502 s = NW_XML_Data_to_String (pT,I_attrVal,tempStr); |
|
503 |
|
504 if (NW_STAT_IS_FAILURE(s)) |
|
505 { |
|
506 return s; |
|
507 } |
|
508 |
|
509 s = NW_String_concatenate(attrValStr,tempStr,pT->encoding); |
|
510 |
|
511 |
|
512 if (NW_STAT_IS_FAILURE(s)) |
|
513 { |
|
514 return s; |
|
515 } |
|
516 |
|
517 // Do some clean up |
|
518 |
|
519 if(tempStr != NULL) |
|
520 { |
|
521 NW_String_delete(tempStr); |
|
522 tempStr = NULL; |
|
523 } |
|
524 |
|
525 }//end if(tempBufLen > 0) |
|
526 |
|
527 // Write the entity content now. There are two possibilities for entities. |
|
528 // |
|
529 // 1) If it is character or decimal or predefined entities. |
|
530 // In this case, intEntityValStr = NULL. |
|
531 // |
|
532 // 2) If it is "Internal Entity" then In this case, entityVal = 0; |
|
533 |
|
534 if (intEntityValStr == NULL) |
|
535 { |
|
536 |
|
537 /* convert contents of the character/predfined entity to string */ |
|
538 |
|
539 s = NW_String_entityToString(entityVal,&entityValStr,pT->encoding); |
|
540 |
|
541 if (NW_STAT_IS_FAILURE(s)) |
|
542 { |
|
543 return s; |
|
544 } |
|
545 }/*end if (intEntityValStr == NULL)*/ |
|
546 else if(entityVal == 0) |
|
547 { |
|
548 /* This is a internal entity string */ |
|
549 |
|
550 s = NW_String_initialize(&entityValStr,intEntityValStr,pT->encoding); |
|
551 if (NW_STAT_IS_FAILURE(s)) |
|
552 { |
|
553 return s; |
|
554 } |
|
555 } /*end else if(entityVal == 0)*/ |
|
556 |
|
557 /* Add this entity value to the string */ |
|
558 |
|
559 s = NW_String_concatenate(attrValStr,&entityValStr,pT->encoding); |
|
560 |
|
561 if (NW_STAT_IS_FAILURE(s)) |
|
562 { |
|
563 return s; |
|
564 } |
|
565 |
|
566 |
|
567 |
|
568 if(entityValStr.storage != NULL) |
|
569 { |
|
570 NW_Mem_Free (entityValStr.storage); |
|
571 } |
|
572 // Initialize the entity string for next entity |
|
573 |
|
574 NW_String_initialize (&entityValStr, NULL, 0); |
|
575 |
|
576 //Again start the top level interval |
|
577 |
|
578 NW_XML_Reader_Interval_Init(pI); |
|
579 NW_XML_Reader_Interval_Start(pI, pT); |
|
580 |
|
581 /*Check for the closing quotes after entity parsing */ |
|
582 |
|
583 if (isOpenSingleQuote) { |
|
584 ssq = NW_XML_Reader_AsciiCharMatch(pT, '\'', &isCloseSingleQuote); |
|
585 } |
|
586 if (isOpenDoubleQuote) { |
|
587 sdq = NW_XML_Reader_AsciiCharMatch(pT, '\"', &isCloseDoubleQuote); |
|
588 } |
|
589 slt = NW_XML_Reader_AsciiCharMatch(pT, '<', &isLessThan); |
|
590 if (NW_STAT_IS_FAILURE(ssq) || NW_STAT_IS_FAILURE(sdq) |
|
591 || NW_STAT_IS_FAILURE(slt) || isLessThan) { |
|
592 return NW_STAT_FAILURE; |
|
593 } |
|
594 entityFoundOnce = CXML_TRUE; |
|
595 }//endif(entityFoundLevel_2 == CXML_TRUE) |
|
596 else |
|
597 { |
|
598 /* If it is here, the entity is not well formed or a entity is |
|
599 * not supported. But, it is error for now. |
|
600 */ |
|
601 /* |
|
602 return NW_STAT_XHTML_BAD_CONTENT;*/ |
|
603 |
|
604 //No valid entity found. Parse as the normal string |
|
605 NW_XML_Reader_SetPosition(pT, |
|
606 prevIndex, |
|
607 prevCharIndex, |
|
608 &prevLineColumn); |
|
609 } |
|
610 |
|
611 } //end if (entityFound && inContent) |
|
612 else |
|
613 { |
|
614 //No valid entity found. Parse as the normal string |
|
615 NW_XML_Reader_SetPosition(pT, |
|
616 prevIndex, |
|
617 prevCharIndex, |
|
618 &prevLineColumn); |
|
619 }//end else |
|
620 } //end match |
|
621 } //end if( !isCloseSingleQuote && !isCloseDoubleQuote) |
|
622 |
|
623 |
|
624 |
|
625 if ((isOpenSingleQuote & isCloseSingleQuote) |
|
626 | (isOpenDoubleQuote & isCloseDoubleQuote)) { |
|
627 break; |
|
628 } |
|
629 |
|
630 if(entityFoundLevel_2 != CXML_TRUE) |
|
631 { |
|
632 s = NW_XML_Reader_Advance(pT); |
|
633 } |
|
634 else |
|
635 { |
|
636 entityFoundLevel_2 = CXML_FALSE; |
|
637 } |
|
638 }//end for (;;) |
|
639 NW_XML_Reader_Interval_Stop(pI, pT); |
|
640 s = NW_XML_Reader_Advance(pT); |
|
641 |
|
642 |
|
643 if( (*entityCheck == CXML_TRUE) && |
|
644 ( (entityFoundLevel_2 == CXML_TRUE) || (entityFoundOnce == CXML_TRUE) ) ) |
|
645 { |
|
646 /* Get rest of the attribute value contents */ |
|
647 |
|
648 |
|
649 tempBufLen = pI->stop - pI->start; |
|
650 |
|
651 if(tempBufLen > 0) |
|
652 { |
|
653 if(tempStr == NULL) |
|
654 { |
|
655 tempStr = NW_String_new(); |
|
656 if(tempStr == NULL) |
|
657 { |
|
658 return NW_STAT_OUT_OF_MEMORY; |
|
659 } |
|
660 |
|
661 } /*end if(tempStr == NULL)*/ |
|
662 s = NW_XML_Data_to_String (pT,pI,tempStr); |
|
663 |
|
664 if (NW_STAT_IS_FAILURE(s)) |
|
665 { |
|
666 return s; |
|
667 } |
|
668 |
|
669 |
|
670 s = NW_String_concatenate(attrValStr,tempStr,pT->encoding); |
|
671 |
|
672 if (NW_STAT_IS_FAILURE(s)) |
|
673 { |
|
674 return s; |
|
675 } |
|
676 |
|
677 // Do some clean up |
|
678 |
|
679 if(tempStr != NULL) |
|
680 { |
|
681 NW_String_delete(tempStr); |
|
682 tempStr = NULL; |
|
683 } |
|
684 |
|
685 }//endif(tempBufLen > 0) |
|
686 |
|
687 }//end if( (*entityCheck == CXML_TRUE) && (entityFoundLevel_2 == CXML_TRUE) ) |
|
688 else |
|
689 { |
|
690 *entityCheck = CXML_FALSE; |
|
691 } |
|
692 |
|
693 return s; |
|
694 } |
|
695 |
|
696 /* |
|
697 Parses an XML attribute (production ???) in Reader. |
|
698 If no parse error, then ti_name and ti_attvalue mark the two items. |
|
699 Allows for leading whitespace. If l is > 0 then p is a "string" of |
|
700 length l that is the name that must match (parse error if doesn't). |
|
701 Assumes position in Reader is at whitespace before or first character |
|
702 of attribute. |
|
703 return: *pMatch = 1 if keyword or attribute name found |
|
704 |
|
705 Careful about the "entity" parameter passed. This is used both as |
|
706 IN/OUT paramter. |
|
707 |
|
708 IN --> if(entity == CXML_TRUE): Then parse attribute value for the |
|
709 entities. |
|
710 |
|
711 OUT --> (entity=CXML_TRUE): The entity is found in the attribute value. |
|
712 */ |
|
713 |
|
714 |
|
715 static |
|
716 NW_Status_t |
|
717 NW_XML_Parse_AttributeValueConsume(NW_XML_Reader_t* pT, |
|
718 NW_XML_Reader_Interval_t* pI_name, |
|
719 NW_XML_Reader_Interval_t* pI_attvalue, |
|
720 NW_Uint32 l, const NW_Uint8* pKeyword, |
|
721 NW_Uint32* pMatch, |
|
722 CXML_Bool* entity, NW_String_t* attrValStr, |
|
723 const RPointerArray <CXML_Internal_Entity_t>* internalEntityList) |
|
724 { |
|
725 /* |
|
726 [41] Attribute ::= Name Eq AttValue |
|
727 where Name is possibly a keyword that must match |
|
728 */ |
|
729 NW_Status_t s; |
|
730 NW_Uint32 match; |
|
731 NW_Uint32 prevIndex0; |
|
732 NW_Uint32 prevIndex1; |
|
733 NW_Uint32 prevCharIndex0; |
|
734 NW_Uint32 prevCharIndex1; |
|
735 NW_XML_Reader_LineColumn_t prevLineColumn0; |
|
736 NW_XML_Reader_LineColumn_t prevLineColumn1; |
|
737 |
|
738 *pMatch = 0; |
|
739 |
|
740 /* S mandatory */ |
|
741 NW_XML_Reader_GetPosition(pT, &prevIndex0, &prevCharIndex0, &prevLineColumn0); |
|
742 s = NW_XML_Reader_SkipSpace(pT); |
|
743 if (NW_STAT_IS_FAILURE(s)) { |
|
744 return s; |
|
745 } |
|
746 NW_XML_Reader_GetPosition(pT, &prevIndex1, &prevCharIndex1, &prevLineColumn1); |
|
747 if (prevIndex0 == prevIndex1) { |
|
748 return NW_STAT_FAILURE; |
|
749 } |
|
750 /* Name */ |
|
751 if ((l != 0U) && (pKeyword != NULL)) { |
|
752 s = NW_XML_Parse_KeywordConsume(pT, pI_name, l, pKeyword, pMatch); |
|
753 if (NW_STAT_IS_SUCCESS(s) && !*pMatch) { |
|
754 /* backup so mandatory space not consumed */ |
|
755 NW_XML_Reader_SetPosition(pT, prevIndex0, prevCharIndex0, &prevLineColumn0); |
|
756 } |
|
757 } else { |
|
758 s = NW_XML_Parse_NameConsume(pT, pI_name, pMatch); |
|
759 } |
|
760 if (NW_STAT_IS_FAILURE(s) || !*pMatch) { |
|
761 return NW_STAT_FAILURE; |
|
762 } |
|
763 /* S */ |
|
764 s = NW_XML_Reader_SkipSpace(pT); |
|
765 if (NW_STAT_IS_FAILURE(s)) { |
|
766 return s; |
|
767 } |
|
768 /* = */ |
|
769 s = NW_XML_Reader_AsciiCharMatch(pT, '=', &match); |
|
770 if (NW_STAT_IS_FAILURE(s) || !match) { |
|
771 return NW_STAT_FAILURE; |
|
772 } |
|
773 s = NW_XML_Reader_Advance(pT); |
|
774 if (NW_STAT_IS_FAILURE(s)) { |
|
775 return NW_STAT_FAILURE; |
|
776 } |
|
777 /* S */ |
|
778 s = NW_XML_Reader_SkipSpace(pT); |
|
779 if (NW_STAT_IS_FAILURE(s)) { |
|
780 return s; |
|
781 } |
|
782 /* attValue */ |
|
783 |
|
784 if(*entity == CXML_FALSE) |
|
785 { |
|
786 return NW_XML_Parse_ValueConsume(pT, pI_attvalue,entity,NULL, internalEntityList); |
|
787 } |
|
788 else |
|
789 { |
|
790 return NW_XML_Parse_ValueConsume(pT, pI_attvalue,entity,attrValStr, internalEntityList); |
|
791 } |
|
792 } |
|
793 |
|
794 /* |
|
795 Parses an XML Comment (production 15) in Reader. |
|
796 If no parse error, then ti marks the Comment--all chars |
|
797 between the start and end marks including spaces. |
|
798 Assumes position in Reader is the character after "<!--". |
|
799 */ |
|
800 static |
|
801 NW_Status_t |
|
802 NW_XML_Parse_CommentConsume(NW_XML_Reader_t* pT, NW_XML_Reader_Interval_t* pI, |
|
803 const struct NW_XML_Parser_EventCallbacks_s* pE) |
|
804 { |
|
805 /* |
|
806 [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->' |
|
807 |
|
808 Note: the pattern with (Char - '-') means that the comment cannot |
|
809 end with '--->' although it can begin with '<!--...'. |
|
810 |
|
811 Also, '--' may not appear in a comment. |
|
812 BUG not yet implemented |
|
813 */ |
|
814 NW_Status_t s; |
|
815 NW_Uint32 match; |
|
816 |
|
817 NW_XML_Reader_Interval_Start(pI, pT); |
|
818 for (;;) { |
|
819 s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_CommentStopLength, |
|
820 NW_XML_String_CommentStop, &match); |
|
821 if (NW_STAT_IS_FAILURE(s)) { |
|
822 return NW_STAT_FAILURE; |
|
823 } |
|
824 if (match) { |
|
825 break; |
|
826 } |
|
827 s = NW_XML_Reader_Advance(pT); |
|
828 if (NW_STAT_IS_FAILURE(s)) { |
|
829 return NW_STAT_FAILURE; |
|
830 } |
|
831 } |
|
832 NW_XML_Reader_Interval_Stop(pI, pT); |
|
833 s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_CommentStopLength); |
|
834 NW_ASSERT(NW_STAT_IS_SUCCESS(s)); /* should never fail */ |
|
835 if (pE->Comment_CB != NULL) { |
|
836 s = (*(pE->Comment_CB))(pT, pI, pE->pClientPointer); |
|
837 } |
|
838 return s; |
|
839 } |
|
840 |
|
841 /* |
|
842 Parses things that start with "<?". These are XMLDecl, TextDecl and |
|
843 the Processing Instruction. On return the formType distinguishes which one |
|
844 was consumed. If it was a PI then ti_name marks the PITarget and |
|
845 ti_content marks the text "argument" of the PI. If it was an XMLDecl |
|
846 (or TextDecl) then examine the booleans to see if various attributes appeared. |
|
847 Note that XMLDecl must have VersionInfo and a TextDecl must not have an SDDecl. |
|
848 Neither XMLDecl or TextDecl should have additional content |
|
849 (i.e., *ti_contentValid should be 0). |
|
850 Assumes position in Reader is the character after "<?". |
|
851 */ |
|
852 static |
|
853 NW_Status_t |
|
854 NW_XML_Parse_PiFormConsume(NW_XML_Reader_t* pT, NW_PiFormTypeTag_t* pFormType, |
|
855 NW_Uint32* pNameValid, |
|
856 NW_XML_Reader_Interval_t* pI_name, |
|
857 NW_Uint32* pVersionValid, |
|
858 NW_XML_Reader_Interval_t* pI_version, |
|
859 NW_Uint32* pEncodingValid, |
|
860 NW_XML_Reader_Interval_t* pI_encoding, |
|
861 NW_Uint32* pStandaloneValid, |
|
862 NW_XML_Reader_Interval_t* pI_standalone, |
|
863 NW_Uint32* pContentValid, |
|
864 NW_XML_Reader_Interval_t* pI_content, |
|
865 const RPointerArray <CXML_Internal_Entity_t>* internalEntityList) |
|
866 { |
|
867 /* |
|
868 [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>' |
|
869 |
|
870 [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l')) |
|
871 |
|
872 when name is an XMLDecl or TextDecl then parse according to |
|
873 |
|
874 [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' |
|
875 |
|
876 [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>' |
|
877 |
|
878 [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" |
|
879 | '"' VersionNum '"') |
|
880 |
|
881 [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+ |
|
882 |
|
883 [80] EncodingDecl ::= S 'encoding' Eq |
|
884 ('"' EncName '"' | "'" EncName "'" ) |
|
885 |
|
886 [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')* |
|
887 |
|
888 [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") |
|
889 | ('"' ('yes' | 'no') '"')) |
|
890 |
|
891 */ |
|
892 NW_Status_t s; |
|
893 NW_XML_Reader_Interval_t I_keyword; |
|
894 NW_Uint32 prevIndex; |
|
895 NW_Uint32 prevCharIndex; |
|
896 NW_XML_Reader_LineColumn_t prevLineColumn; |
|
897 NW_Uint32 match; |
|
898 NW_Uint32 i; |
|
899 CXML_Bool entity = CXML_FALSE; |
|
900 |
|
901 |
|
902 *pNameValid = *pVersionValid = *pEncodingValid = 0; |
|
903 *pStandaloneValid = *pContentValid = 0; |
|
904 *pFormType = UNKNOWFORM; |
|
905 |
|
906 |
|
907 s = NW_STAT_FAILURE; |
|
908 match = 0; |
|
909 /* Will back up if "xml" is part of a longer name like "xml-stylesheet". */ |
|
910 NW_XML_Reader_GetPosition(pT, |
|
911 &prevIndex, &prevCharIndex, &prevLineColumn); |
|
912 for (i = 0; i < NW_XML_String_XmlNameVariationCount; i++) { |
|
913 s = NW_XML_Parse_KeywordConsume(pT, pI_name, |
|
914 NW_XML_String_XmlLength, |
|
915 (NW_XML_String_XmlVariations |
|
916 + NW_XML_String_XmlLength * i), |
|
917 &match); |
|
918 if (NW_STAT_IS_SUCCESS(s) && match) { |
|
919 /* Make sure that the "xml" variant isn't part of a longer name */ |
|
920 NW_Uint32 m; |
|
921 /* look for end of piform */ |
|
922 s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_PiFormStopLength, |
|
923 NW_XML_String_PiFormStop, &m); |
|
924 if (NW_STAT_IS_SUCCESS(s) && m) { |
|
925 break; |
|
926 } |
|
927 /* look for whitespace */ |
|
928 s = NW_XML_Reader_IsSpace(pT, &m); |
|
929 if (NW_STAT_IS_SUCCESS(s) && m) { |
|
930 break; |
|
931 } |
|
932 /* if get here then "xml" variant is part of a longer name, |
|
933 fail match, back up and shortcut out of loop */ |
|
934 match = 0; |
|
935 NW_XML_Reader_SetPosition(pT, |
|
936 prevIndex, |
|
937 prevCharIndex, |
|
938 &prevLineColumn); |
|
939 i = NW_XML_String_XmlNameVariationCount; |
|
940 break; |
|
941 } |
|
942 } |
|
943 |
|
944 if (NW_STAT_IS_SUCCESS(s) && !match) { |
|
945 s = NW_XML_Parse_NameConsume(pT, pI_name, &match); |
|
946 } |
|
947 if (NW_STAT_IS_FAILURE(s) || !match) { |
|
948 return NW_STAT_FAILURE; |
|
949 } |
|
950 *pNameValid = 1; |
|
951 |
|
952 /* Support all the XML declaration starting with any possible combination. */ |
|
953 |
|
954 if (i < NW_XML_String_XmlNameVariationCount) |
|
955 { |
|
956 /* BUG there is currently no checking of legal values according |
|
957 to productions 26, 81 and 32 */ |
|
958 *pFormType = XMLDECL; |
|
959 s = NW_XML_Parse_AttributeValueConsume(pT, &I_keyword, pI_version, |
|
960 NW_XML_String_VersionLength, |
|
961 NW_XML_String_Version, &match, |
|
962 &entity,NULL, |
|
963 internalEntityList); |
|
964 if (NW_STAT_IS_FAILURE(s)) { |
|
965 if (match) { |
|
966 return NW_STAT_FAILURE; /* couldn't parse version value */ |
|
967 } |
|
968 } else { |
|
969 if (match) { |
|
970 *pVersionValid = 1; |
|
971 } |
|
972 } |
|
973 s = NW_XML_Parse_AttributeValueConsume(pT, &I_keyword, pI_encoding, |
|
974 NW_XML_String_EncodingLength, |
|
975 NW_XML_String_Encoding, &match, |
|
976 &entity,NULL,internalEntityList); |
|
977 if (NW_STAT_IS_FAILURE(s)) { |
|
978 if (match) { |
|
979 return NW_STAT_FAILURE; /* couldn't parse encoding value */ |
|
980 } |
|
981 } else { |
|
982 if (match) { |
|
983 *pEncodingValid = 1; |
|
984 } |
|
985 } |
|
986 s = NW_XML_Parse_AttributeValueConsume(pT, &I_keyword, pI_standalone, |
|
987 NW_XML_String_StandaloneLength, |
|
988 NW_XML_String_Standalone, &match, |
|
989 &entity,NULL,internalEntityList); |
|
990 if (NW_STAT_IS_FAILURE(s)) { |
|
991 if (match) { |
|
992 return NW_STAT_FAILURE; /* couldn't parse standalone value */ |
|
993 } |
|
994 } else { |
|
995 if (match) { |
|
996 *pStandaloneValid = 1; |
|
997 } |
|
998 } |
|
999 } else { |
|
1000 *pFormType = PI; |
|
1001 } |
|
1002 s = NW_XML_Reader_SkipSpace(pT); |
|
1003 if (NW_STAT_IS_FAILURE(s)) { |
|
1004 return NW_STAT_FAILURE; |
|
1005 } |
|
1006 NW_XML_Reader_Interval_Start(pI_content, pT); |
|
1007 for (;;) { |
|
1008 s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_PiFormStopLength, |
|
1009 NW_XML_String_PiFormStop, &match); |
|
1010 if (NW_STAT_IS_FAILURE(s)) { |
|
1011 return NW_STAT_FAILURE; |
|
1012 } |
|
1013 if (match) { |
|
1014 break; |
|
1015 } |
|
1016 s = NW_XML_Reader_Advance(pT); |
|
1017 if (NW_STAT_IS_FAILURE(s)) { |
|
1018 return NW_STAT_FAILURE; |
|
1019 } |
|
1020 } |
|
1021 NW_XML_Reader_Interval_Stop(pI_content, pT); |
|
1022 if (pI_content->start == pI_content->stop) { |
|
1023 *pContentValid = 0; |
|
1024 } else { |
|
1025 *pContentValid = 1; |
|
1026 } |
|
1027 s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_PiFormStopLength); |
|
1028 NW_ASSERT(NW_STAT_IS_SUCCESS(s)); /* should never fail */ |
|
1029 return s; |
|
1030 } |
|
1031 |
|
1032 /* Assumes position is either at whitespace or beginning of text. */ |
|
1033 static |
|
1034 NW_Status_t |
|
1035 NW_XML_Parse_MiscConsume(NW_XML_Reader_t* pT, |
|
1036 const struct NW_XML_Parser_EventCallbacks_s* pE, |
|
1037 const RPointerArray <CXML_Internal_Entity_t>* internalEntityList) |
|
1038 { |
|
1039 /* |
|
1040 [27] Misc ::= Comment | PI | S |
|
1041 |
|
1042 Note: All invocations of this production take the form "Misc*" |
|
1043 */ |
|
1044 NW_Status_t s; |
|
1045 NW_XML_Reader_Interval_t I; |
|
1046 NW_Uint32 match; |
|
1047 NW_Uint32 prevIndex0; /* will do while there is advancement thru Reader */ |
|
1048 NW_Uint32 prevIndex1; /* will do while there is advancement thru Reader */ |
|
1049 NW_Uint32 prevCharIndex; /* ignored */ |
|
1050 NW_XML_Reader_LineColumn_t prevLineColumn; /* ignored */ |
|
1051 do { |
|
1052 NW_XML_Reader_GetPosition(pT, &prevIndex0, &prevCharIndex, &prevLineColumn); |
|
1053 s = NW_XML_Reader_SkipSpace(pT); |
|
1054 if (NW_STAT_IS_FAILURE(s)) { |
|
1055 return NW_STAT_FAILURE; |
|
1056 } |
|
1057 |
|
1058 if(pT->end){ |
|
1059 break; |
|
1060 } |
|
1061 s = NW_XML_Parse_KeywordConsume(pT, &I, |
|
1062 NW_XML_String_CommentStartLength, |
|
1063 NW_XML_String_CommentStart, &match); |
|
1064 if (NW_STAT_IS_FAILURE(s)) { |
|
1065 return NW_STAT_FAILURE; |
|
1066 } |
|
1067 if (match) { |
|
1068 s = NW_XML_Parse_CommentConsume(pT, &I, pE); |
|
1069 if (NW_STAT_IS_FAILURE(s)) { |
|
1070 return NW_STAT_FAILURE; |
|
1071 } |
|
1072 } else { |
|
1073 s = NW_XML_Parse_KeywordConsume(pT, &I, |
|
1074 NW_XML_String_PiFormStartLength, |
|
1075 NW_XML_String_PiFormStart, &match); |
|
1076 if (NW_STAT_IS_FAILURE(s)) { |
|
1077 return NW_STAT_FAILURE; |
|
1078 } |
|
1079 if (match) { |
|
1080 NW_PiFormTypeTag_t pi_type; |
|
1081 NW_XML_Reader_Interval_t I_name, I_version, I_encoding, I_standalone; |
|
1082 NW_XML_Reader_Interval_t I_content; |
|
1083 NW_Uint32 nameValid, versionValid, encodingValid, standaloneValid; |
|
1084 NW_Uint32 contentValid; |
|
1085 s = NW_XML_Parse_PiFormConsume(pT, &pi_type, |
|
1086 &nameValid, |
|
1087 &I_name, |
|
1088 &versionValid, |
|
1089 &I_version, |
|
1090 &encodingValid, |
|
1091 &I_encoding, |
|
1092 &standaloneValid, |
|
1093 &I_standalone, |
|
1094 &contentValid, |
|
1095 &I_content, |
|
1096 internalEntityList); |
|
1097 if (NW_STAT_IS_FAILURE(s) || !nameValid) { |
|
1098 return NW_STAT_FAILURE; |
|
1099 } |
|
1100 if (pi_type != PI) { |
|
1101 /* BUG Is this really an illegal case? */ |
|
1102 return NW_STAT_FAILURE; |
|
1103 } |
|
1104 if (pE->PiForm_CB != NULL) { |
|
1105 s = (*(pE->PiForm_CB))(pT, pi_type, |
|
1106 (nameValid ? &I_name : NULL), |
|
1107 (versionValid ? &I_version : NULL), |
|
1108 (encodingValid ? &I_encoding : NULL), |
|
1109 (standaloneValid ? &I_standalone : NULL), |
|
1110 (contentValid ? &I_content : NULL), |
|
1111 pE->pClientPointer); |
|
1112 } |
|
1113 } |
|
1114 } |
|
1115 NW_XML_Reader_GetPosition(pT, &prevIndex1, &prevCharIndex, &prevLineColumn); |
|
1116 } while (prevIndex0 != prevIndex1); /* do while */ |
|
1117 return NW_STAT_SUCCESS; |
|
1118 } |
|
1119 |
|
1120 |
|
1121 /* on entry position should be just after '<!DOCTYPE' */ |
|
1122 |
|
1123 static |
|
1124 NW_Status_t |
|
1125 NW_XML_Parse_InternalEntity(NW_XML_Reader_t* pT, |
|
1126 RPointerArray <CXML_Internal_Entity_t>* internalEntityList) |
|
1127 { |
|
1128 NW_Status_t s; |
|
1129 NW_XML_Reader_Interval_t I_EntityName; |
|
1130 NW_Uint32 match; |
|
1131 NW_XML_Reader_Interval_t I_EntityValue; |
|
1132 NW_Uint32 quoteChar = 0; /* 0 = double quote, 1 = single quote */ |
|
1133 NW_Uint32 matchDoubleQuote; |
|
1134 NW_Uint32 matchSingleQuote; |
|
1135 NW_Uint32 matchPercentSign; |
|
1136 NW_Status_t statusDoubleQuote; |
|
1137 NW_Status_t statusSingleQuote; |
|
1138 |
|
1139 |
|
1140 |
|
1141 |
|
1142 s = NW_XML_Reader_SkipSpace(pT); |
|
1143 if (NW_STAT_IS_FAILURE(s)) |
|
1144 { |
|
1145 return NW_STAT_FAILURE; |
|
1146 } |
|
1147 |
|
1148 /* The Internal Parameteric Entities has "%" symbol in the beginning of the entity. |
|
1149 * Check for parametric entity has skip the symbol. |
|
1150 */ |
|
1151 |
|
1152 s = NW_XML_Reader_AsciiCharMatch(pT, '%', &matchPercentSign); |
|
1153 |
|
1154 if (NW_STAT_IS_FAILURE(s)) |
|
1155 { |
|
1156 return NW_STAT_FAILURE; |
|
1157 } |
|
1158 |
|
1159 if(matchPercentSign) |
|
1160 { |
|
1161 /*Advance from '%' sign */ |
|
1162 |
|
1163 s = NW_XML_Reader_Advance(pT); |
|
1164 if (NW_STAT_IS_FAILURE(s)) |
|
1165 { |
|
1166 return NW_STAT_FAILURE; |
|
1167 } |
|
1168 |
|
1169 s = NW_XML_Reader_SkipSpace(pT); |
|
1170 |
|
1171 if (NW_STAT_IS_FAILURE(s)) |
|
1172 { |
|
1173 return NW_STAT_FAILURE; |
|
1174 } |
|
1175 |
|
1176 } /*end if(matchPercentSign)*/ |
|
1177 |
|
1178 /* Name */ |
|
1179 |
|
1180 s = NW_XML_Parse_NameConsume(pT, &I_EntityName, &match); |
|
1181 if (NW_STAT_IS_FAILURE(s)) |
|
1182 { |
|
1183 return NW_STAT_FAILURE; |
|
1184 } |
|
1185 |
|
1186 if (!match) |
|
1187 { |
|
1188 /* FATAL bad tag */ |
|
1189 return NW_STAT_FAILURE; |
|
1190 } |
|
1191 |
|
1192 /* S, space may be there after the Entry Name */ |
|
1193 |
|
1194 s = NW_XML_Reader_SkipSpace(pT); |
|
1195 if (NW_STAT_IS_FAILURE(s)) |
|
1196 { |
|
1197 return NW_STAT_FAILURE; |
|
1198 } |
|
1199 |
|
1200 /* Look for opening single or double quote. Let the closing '>' |
|
1201 * be handled in the DTD function. |
|
1202 */ |
|
1203 |
|
1204 statusDoubleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\"', &matchDoubleQuote); |
|
1205 statusSingleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\'', &matchSingleQuote); |
|
1206 |
|
1207 if (NW_STAT_IS_FAILURE(statusDoubleQuote) |
|
1208 || NW_STAT_IS_FAILURE(statusSingleQuote) ) |
|
1209 { |
|
1210 return NW_STAT_FAILURE; |
|
1211 } |
|
1212 |
|
1213 if(matchDoubleQuote || matchSingleQuote) |
|
1214 { |
|
1215 |
|
1216 if(matchSingleQuote) /* Look for corresponding quote */ |
|
1217 { |
|
1218 quoteChar = 1; /* 0 = double quote, 1 = single quote */ |
|
1219 } |
|
1220 /*Advance from the Quote */ |
|
1221 |
|
1222 s = NW_XML_Reader_Advance(pT); |
|
1223 if (NW_STAT_IS_FAILURE(s)) |
|
1224 { |
|
1225 return NW_STAT_FAILURE; |
|
1226 } |
|
1227 |
|
1228 /* Start the Internal for the name space */ |
|
1229 |
|
1230 NW_XML_Reader_Interval_Start(&I_EntityValue, pT); |
|
1231 |
|
1232 for(; ;) |
|
1233 { |
|
1234 statusDoubleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\"', &matchDoubleQuote); |
|
1235 statusSingleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\'', &matchSingleQuote); |
|
1236 |
|
1237 if(matchDoubleQuote || matchSingleQuote) |
|
1238 { |
|
1239 if(!quoteChar && matchDoubleQuote) |
|
1240 { |
|
1241 NW_XML_Reader_Interval_Stop(&I_EntityValue, pT); |
|
1242 break; |
|
1243 } |
|
1244 else if(quoteChar && matchSingleQuote) |
|
1245 { |
|
1246 NW_XML_Reader_Interval_Stop(&I_EntityValue, pT); |
|
1247 break; |
|
1248 } |
|
1249 }/* if(matchDoubleQuote || matchSingleQuote)*/ |
|
1250 |
|
1251 /*Read next character */ |
|
1252 |
|
1253 s = NW_XML_Reader_Advance(pT); |
|
1254 |
|
1255 if (NW_STAT_IS_FAILURE(s)) |
|
1256 { |
|
1257 return NW_STAT_FAILURE; |
|
1258 } |
|
1259 |
|
1260 }/*end for */ |
|
1261 }/*end if(statusDoubleQuote || statusSingleQuote)*/ |
|
1262 |
|
1263 |
|
1264 s = CXML_XML_Parser_Store_I_Entity(pT,&I_EntityName,&I_EntityValue,internalEntityList); |
|
1265 |
|
1266 if(s != NW_STAT_SUCCESS ) |
|
1267 { |
|
1268 return s; |
|
1269 } |
|
1270 |
|
1271 |
|
1272 return NW_STAT_SUCCESS; |
|
1273 |
|
1274 }/*end NW_XML_Parse_InternalEntity() */ |
|
1275 |
|
1276 /* on entry position should be just after '<!DOCTYPE' */ |
|
1277 static |
|
1278 NW_Status_t |
|
1279 NW_XML_Parse_DtdConsume(NW_XML_Reader_t* pT, |
|
1280 RPointerArray <CXML_Internal_Entity_t>* internalEntityList) |
|
1281 { |
|
1282 NW_Status_t s; |
|
1283 NW_XML_Reader_Interval_t I_name; |
|
1284 NW_Uint32 match; |
|
1285 NW_XML_Reader_Interval_t I_keyword; |
|
1286 NW_Uint32 inString = 0; |
|
1287 NW_Uint32 quoteChar = 0; /* 0 = double quote, 1 = single quote */ |
|
1288 NW_Uint32 balance = 1; /* already read opening greater-than sign */ |
|
1289 |
|
1290 /* S */ |
|
1291 s = NW_XML_Reader_SkipSpace(pT); |
|
1292 if (NW_STAT_IS_FAILURE(s)) { |
|
1293 return NW_STAT_FAILURE; |
|
1294 } |
|
1295 /* Name */ |
|
1296 s = NW_XML_Parse_NameConsume(pT, &I_name, &match); |
|
1297 if (NW_STAT_IS_FAILURE(s)) { |
|
1298 return NW_STAT_FAILURE; |
|
1299 } |
|
1300 if (!match) { |
|
1301 /* FATAL bad tag */ |
|
1302 return NW_STAT_FAILURE; |
|
1303 } |
|
1304 /* You can put quoted '<' and '>' in literal value strings which must be ignored. */ |
|
1305 while (balance) { |
|
1306 NW_Uint32 matchDoubleQuote; |
|
1307 NW_Uint32 matchSingleQuote; |
|
1308 NW_Uint32 matchGreaterThan; |
|
1309 NW_Uint32 matchLessThan; |
|
1310 NW_Status_t statusDoubleQuote; |
|
1311 NW_Status_t statusSingleQuote; |
|
1312 NW_Status_t statusGreaterThan; |
|
1313 NW_Status_t statusLessThan; |
|
1314 |
|
1315 statusDoubleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\"', &matchDoubleQuote); |
|
1316 statusSingleQuote = NW_XML_Reader_AsciiCharMatch(pT, '\'', &matchSingleQuote); |
|
1317 statusGreaterThan = NW_XML_Reader_AsciiCharMatch(pT, '>', &matchGreaterThan); |
|
1318 statusLessThan = NW_XML_Reader_AsciiCharMatch(pT, '<', &matchLessThan); |
|
1319 |
|
1320 if (NW_STAT_IS_FAILURE(statusDoubleQuote) |
|
1321 || NW_STAT_IS_FAILURE(statusSingleQuote) |
|
1322 || NW_STAT_IS_FAILURE(statusGreaterThan) |
|
1323 || NW_STAT_IS_FAILURE(statusLessThan)) { |
|
1324 return NW_STAT_FAILURE; |
|
1325 } |
|
1326 |
|
1327 if (inString) { |
|
1328 if (quoteChar) { |
|
1329 if (matchSingleQuote) { |
|
1330 inString = 0; |
|
1331 } |
|
1332 } else if (matchDoubleQuote) { |
|
1333 inString = 0; |
|
1334 } |
|
1335 } else |
|
1336 { |
|
1337 if (matchGreaterThan) |
|
1338 { |
|
1339 NW_ASSERT(balance); |
|
1340 balance--; |
|
1341 } else if (matchLessThan) |
|
1342 { |
|
1343 balance++; |
|
1344 /* '<!ENTITY' */ |
|
1345 s = NW_XML_Parse_KeywordConsume(pT, &I_keyword, |
|
1346 NW_XML_String_EntityStartLength, |
|
1347 NW_XML_String_EntityStart, &match); |
|
1348 if (NW_STAT_IS_FAILURE(s)) |
|
1349 { |
|
1350 return NW_STAT_FAILURE; |
|
1351 } |
|
1352 if (match) |
|
1353 { |
|
1354 s = NW_XML_Parse_InternalEntity(pT,internalEntityList); |
|
1355 if (NW_STAT_IS_FAILURE(s)) |
|
1356 { |
|
1357 return NW_STAT_FAILURE; |
|
1358 } |
|
1359 } |
|
1360 } else if (matchSingleQuote) |
|
1361 { |
|
1362 quoteChar = 1; |
|
1363 inString = 1; |
|
1364 } |
|
1365 else if (matchDoubleQuote) |
|
1366 { |
|
1367 quoteChar = 0; |
|
1368 inString = 1; |
|
1369 } |
|
1370 } /*end else */ |
|
1371 s = NW_XML_Reader_Advance(pT); |
|
1372 if (NW_STAT_IS_FAILURE(s)) { |
|
1373 return NW_STAT_FAILURE; |
|
1374 } |
|
1375 } |
|
1376 return NW_STAT_SUCCESS; |
|
1377 } |
|
1378 |
|
1379 static |
|
1380 NW_Status_t |
|
1381 NW_XML_Parse_PrologConsume(NW_XML_Reader_t* pT, |
|
1382 const struct NW_XML_Parser_EventCallbacks_s* pE, |
|
1383 RPointerArray <CXML_Internal_Entity_t>* internalEntityList) |
|
1384 { |
|
1385 /* |
|
1386 [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)? |
|
1387 |
|
1388 [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' |
|
1389 |
|
1390 [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" |
|
1391 | '"' VersionNum '"') |
|
1392 |
|
1393 [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+ |
|
1394 */ |
|
1395 |
|
1396 /* '<?' */ |
|
1397 NW_Status_t s; |
|
1398 NW_Uint32 match; |
|
1399 NW_PiFormTypeTag_t pi_type; |
|
1400 NW_Uint32 nameValid; |
|
1401 NW_XML_Reader_Interval_t I_name; |
|
1402 NW_Uint32 versionValid; |
|
1403 NW_XML_Reader_Interval_t I_version; |
|
1404 NW_Uint32 encodingValid; |
|
1405 NW_XML_Reader_Interval_t I_encoding; |
|
1406 NW_Uint32 standaloneValid; |
|
1407 NW_XML_Reader_Interval_t I_standalone; |
|
1408 NW_Uint32 contentValid; |
|
1409 NW_XML_Reader_Interval_t I_content; |
|
1410 NW_XML_Reader_Interval_t I_keyword; |
|
1411 NW_Uint32 prevIndex; |
|
1412 NW_Uint32 prevCharIndex; |
|
1413 NW_XML_Reader_LineColumn_t prevLineColumn; |
|
1414 |
|
1415 /* Might back up if PiForm is from Misc */ |
|
1416 NW_XML_Reader_GetPosition(pT, &prevIndex, &prevCharIndex, &prevLineColumn); |
|
1417 |
|
1418 s = NW_XML_Parse_KeywordConsume(pT, &I_keyword, |
|
1419 NW_XML_String_PiFormStartLength, |
|
1420 NW_XML_String_PiFormStart, &match); |
|
1421 if (NW_STAT_IS_FAILURE(s)) { |
|
1422 return NW_STAT_FAILURE; |
|
1423 } |
|
1424 if (match) { |
|
1425 NW_Uint32 error = 0; |
|
1426 /* XMLDecl */ |
|
1427 s = NW_XML_Parse_PiFormConsume(pT, &pi_type, |
|
1428 &nameValid, |
|
1429 &I_name, |
|
1430 &versionValid, |
|
1431 &I_version, |
|
1432 &encodingValid, |
|
1433 &I_encoding, |
|
1434 &standaloneValid, |
|
1435 &I_standalone, |
|
1436 &contentValid, |
|
1437 &I_content, |
|
1438 internalEntityList); |
|
1439 if (NW_STAT_IS_FAILURE(s) || !nameValid) { |
|
1440 return NW_STAT_FAILURE; |
|
1441 } |
|
1442 switch (pi_type) { |
|
1443 case XMLDECL: |
|
1444 /* BUG not checking for legal values of version, |
|
1445 encoding and standalone */ |
|
1446 if (!versionValid) { |
|
1447 /* version is mandatory */ |
|
1448 error = 1; |
|
1449 } |
|
1450 if (contentValid) { |
|
1451 /* no other attribute info is legal */ |
|
1452 error = 1; |
|
1453 } |
|
1454 if (!error && (pE->PiForm_CB != NULL)) { |
|
1455 s = (*(pE->PiForm_CB))(pT, pi_type, |
|
1456 (nameValid ? &I_name : NULL), |
|
1457 (versionValid ? &I_version : NULL), |
|
1458 (encodingValid ? &I_encoding : NULL), |
|
1459 (standaloneValid ? &I_standalone : NULL), |
|
1460 (contentValid ? &I_content : NULL), |
|
1461 pE->pClientPointer); |
|
1462 } |
|
1463 break; |
|
1464 case PI: |
|
1465 /* encountered a PI from Misc, rewind and continue */ |
|
1466 NW_XML_Reader_SetPosition(pT, prevIndex, prevCharIndex, &prevLineColumn); |
|
1467 break; |
|
1468 default: |
|
1469 error = 1; |
|
1470 break; |
|
1471 } |
|
1472 if (error) { |
|
1473 if (pE->Exception_CB != NULL) { |
|
1474 s = (*(pE->Exception_CB))(pT, pE->pClientPointer); |
|
1475 } |
|
1476 return NW_STAT_FAILURE; |
|
1477 } |
|
1478 } |
|
1479 /* MISC */ |
|
1480 s = NW_XML_Parse_MiscConsume(pT, pE,internalEntityList); |
|
1481 if (NW_STAT_IS_FAILURE(s)) { |
|
1482 return NW_STAT_FAILURE; |
|
1483 } |
|
1484 /* '<!DOCTYPE' */ |
|
1485 s = NW_XML_Parse_KeywordConsume(pT, &I_keyword, |
|
1486 NW_XML_String_DoctypeStartLength, |
|
1487 NW_XML_String_DoctypeStart, &match); |
|
1488 if (NW_STAT_IS_FAILURE(s)) { |
|
1489 return NW_STAT_FAILURE; |
|
1490 } |
|
1491 if (match) { |
|
1492 s = NW_XML_Parse_DtdConsume(pT,internalEntityList); |
|
1493 if (NW_STAT_IS_FAILURE(s)) { |
|
1494 return NW_STAT_FAILURE; |
|
1495 } |
|
1496 } |
|
1497 /* MISC */ |
|
1498 s = NW_XML_Parse_MiscConsume(pT, pE,internalEntityList); |
|
1499 if (NW_STAT_IS_FAILURE(s)) { |
|
1500 return NW_STAT_FAILURE; |
|
1501 } |
|
1502 return NW_STAT_SUCCESS; |
|
1503 } |
|
1504 |
|
1505 /* Assumes read position is at '<' on entry. |
|
1506 return: *pIsEmptyElement = 1 if it is an EmptyElemTag. */ |
|
1507 static |
|
1508 NW_Status_t |
|
1509 NW_XML_Parse_ElementOpeningMarkupConsume(NW_XML_Reader_t* pT, |
|
1510 NW_Uint32* pIsEmptyElement, |
|
1511 const struct |
|
1512 NW_XML_Parser_EventCallbacks_s* pE, |
|
1513 const RPointerArray <CXML_Internal_Entity_t>* internalEntityList) |
|
1514 { |
|
1515 /* |
|
1516 [40] STag ::= '<' Name (S Attribute)* S? '>' |
|
1517 |
|
1518 [41] Attribute ::= Name Eq AttValue |
|
1519 |
|
1520 [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>' |
|
1521 */ |
|
1522 |
|
1523 NW_Status_t s; |
|
1524 NW_XML_Reader_Interval_t I_name; |
|
1525 NW_XML_Reader_Interval_t I_attName; |
|
1526 NW_XML_Reader_Interval_t I_attValue; |
|
1527 NW_Uint32 match; |
|
1528 NW_Uint32 attributeCount; |
|
1529 CXML_Bool entity = CXML_TRUE; |
|
1530 NW_String_t attrValStr; |
|
1531 NW_Byte* finalStr = NULL; |
|
1532 NW_Uint32 finalStrLen = 0; |
|
1533 NW_String_initialize (&attrValStr, NULL, 0); |
|
1534 |
|
1535 |
|
1536 *pIsEmptyElement = 0; |
|
1537 /* '<' */ |
|
1538 s = NW_XML_Reader_AsciiCharMatch(pT, '<', &match); |
|
1539 if (NW_STAT_IS_FAILURE(s) || !match) { |
|
1540 return NW_STAT_FAILURE; |
|
1541 } |
|
1542 s = NW_XML_Reader_Advance(pT); |
|
1543 if (NW_STAT_IS_FAILURE(s)) { |
|
1544 return NW_STAT_FAILURE; |
|
1545 } |
|
1546 /* Name */ |
|
1547 s = NW_XML_Parse_NameConsume(pT, &I_name, &match); |
|
1548 if (NW_STAT_IS_FAILURE(s) || !match) { |
|
1549 return NW_STAT_FAILURE; |
|
1550 } |
|
1551 if (pE->Tag_Start_CB != NULL) { |
|
1552 s = (*(pE->Tag_Start_CB))(pT, &I_name, pE->pClientPointer); |
|
1553 if (NW_STAT_IS_FAILURE(s)) { |
|
1554 return NW_STAT_FAILURE; |
|
1555 } |
|
1556 } |
|
1557 /* Do attribute value consume and look for closing markup. */ |
|
1558 for (attributeCount = 0;;) { |
|
1559 entity = CXML_TRUE; |
|
1560 s = NW_XML_Parse_AttributeValueConsume(pT, &I_attName, &I_attValue, |
|
1561 0, NULL, &match, |
|
1562 &entity,&attrValStr,internalEntityList); |
|
1563 |
|
1564 if (NW_STAT_IS_SUCCESS(s) && match && (entity != CXML_TRUE) ) { |
|
1565 attributeCount++; |
|
1566 if (pE->Attr_Start_CB != NULL) { |
|
1567 s = (*(pE->Attr_Start_CB))(pT, &I_attName, pE->pClientPointer); |
|
1568 if (NW_STAT_IS_SUCCESS(s)) { |
|
1569 if (pE->Attr_VarVal_CB != NULL) { |
|
1570 s = (*(pE->Attr_VarVal_CB))(pT, &I_attName, &I_attValue, |
|
1571 pE->pClientPointer); |
|
1572 } |
|
1573 } |
|
1574 if (NW_STAT_IS_FAILURE(s)) { |
|
1575 return NW_STAT_FAILURE; |
|
1576 } |
|
1577 if(attrValStr.storage != NULL) |
|
1578 { |
|
1579 NW_Mem_Free(attrValStr.storage); |
|
1580 } |
|
1581 NW_String_initialize (&attrValStr, NULL, 0); |
|
1582 } |
|
1583 continue; |
|
1584 } |
|
1585 else if(NW_STAT_IS_SUCCESS(s) && match && (entity == CXML_TRUE) ) |
|
1586 { |
|
1587 attributeCount++; |
|
1588 if (pE->Attr_Start_CB != NULL) { |
|
1589 s = (*(pE->Attr_Start_CB))(pT, &I_attName, pE->pClientPointer); |
|
1590 if (NW_STAT_IS_SUCCESS(s)) { |
|
1591 if (pE->Attr_Entity_VarVal_CB != NULL) { |
|
1592 /* The MSB of NW_Byte length if set represents that the |
|
1593 string is from storage buffer, so BufferOwns String. So, |
|
1594 find exact length. |
|
1595 */ |
|
1596 finalStrLen = attrValStr.length & 0x7fffffff; |
|
1597 |
|
1598 /* This string is with the NULL terminate character. But, |
|
1599 * the callback function Attr_Entity_VarVal_CB(..) requires |
|
1600 * with out this. So, take out NULL termination character |
|
1601 * length depending on the Encoding. |
|
1602 */ |
|
1603 |
|
1604 if ( (pT->encoding == HTTP_iso_10646_ucs_2) && |
|
1605 (finalStrLen > 1) && |
|
1606 (attrValStr.storage[(finalStrLen-1)] == 0) && |
|
1607 (attrValStr.storage[(finalStrLen-2)] == 0) ) |
|
1608 { |
|
1609 finalStrLen--; |
|
1610 finalStrLen--; |
|
1611 } |
|
1612 else if ((pT->encoding == HTTP_utf_8) || |
|
1613 (pT->encoding == HTTP_us_ascii) || |
|
1614 (pT->encoding== HTTP_iso_8859_1)) |
|
1615 { |
|
1616 if ( (finalStrLen > 0) && (attrValStr.storage[finalStrLen-1] == 0) ) |
|
1617 { |
|
1618 finalStrLen--; |
|
1619 } |
|
1620 } |
|
1621 |
|
1622 finalStr = (NW_Byte*) NW_Mem_Malloc(finalStrLen); |
|
1623 if(finalStr == NULL) |
|
1624 { |
|
1625 return NW_STAT_OUT_OF_MEMORY; |
|
1626 } |
|
1627 |
|
1628 CXML_Mem_memcpy(finalStr,attrValStr.storage,finalStrLen); |
|
1629 |
|
1630 s = (*(pE->Attr_Entity_VarVal_CB))(pT, &I_attName, |
|
1631 finalStr,finalStrLen,pE->pClientPointer); |
|
1632 if(finalStr != NULL) |
|
1633 { |
|
1634 NW_Mem_Free(finalStr); |
|
1635 finalStr = NULL; |
|
1636 } |
|
1637 } |
|
1638 } |
|
1639 if (NW_STAT_IS_FAILURE(s)) { |
|
1640 return NW_STAT_FAILURE; |
|
1641 } |
|
1642 |
|
1643 if(attrValStr.storage != NULL) |
|
1644 { |
|
1645 NW_Mem_Free(attrValStr.storage); |
|
1646 } |
|
1647 NW_String_initialize (&attrValStr, NULL, 0); |
|
1648 } |
|
1649 continue; |
|
1650 |
|
1651 }//end else if(NW_STAT_IS_SUCCESS(s) && match && (entity != CXML_TRUE) ) |
|
1652 if (NW_STAT_IS_FAILURE(s) && match) { |
|
1653 return NW_STAT_FAILURE; |
|
1654 } |
|
1655 s = NW_XML_Reader_AsciiCharMatch(pT, '>', &match); |
|
1656 if (NW_STAT_IS_FAILURE(s)) { |
|
1657 return NW_STAT_FAILURE; |
|
1658 } |
|
1659 if (match) { |
|
1660 s = NW_XML_Reader_Advance(pT); |
|
1661 if (NW_STAT_IS_FAILURE(s)) { |
|
1662 return NW_STAT_FAILURE; |
|
1663 } |
|
1664 if (pE->Attributes_End_CB != NULL) { |
|
1665 s = (*(pE->Attributes_End_CB))(pT, attributeCount, |
|
1666 pE->pClientPointer); |
|
1667 if (NW_STAT_IS_FAILURE(s)) { |
|
1668 return NW_STAT_FAILURE; |
|
1669 } |
|
1670 } |
|
1671 break; |
|
1672 } |
|
1673 s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_EmptyTagEndLength, |
|
1674 NW_XML_String_EmptyTagEnd, &match); |
|
1675 if (NW_STAT_IS_FAILURE(s)) { |
|
1676 return NW_STAT_FAILURE; |
|
1677 } |
|
1678 if (match) { |
|
1679 s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_EmptyTagEndLength); |
|
1680 if (NW_STAT_IS_FAILURE(s)) { |
|
1681 return NW_STAT_FAILURE; |
|
1682 } |
|
1683 if (pE->Attributes_End_CB != NULL) { |
|
1684 s = (*(pE->Attributes_End_CB))(pT, attributeCount, |
|
1685 pE->pClientPointer); |
|
1686 if (NW_STAT_IS_FAILURE(s)) { |
|
1687 return NW_STAT_FAILURE; |
|
1688 } |
|
1689 } |
|
1690 *pIsEmptyElement = 1; |
|
1691 if (pE->Tag_End_CB != NULL) { |
|
1692 s = (*(pE->Tag_End_CB))(pT, &I_name, |
|
1693 1, /* empty tag*/ |
|
1694 pE->pClientPointer); |
|
1695 if (NW_STAT_IS_FAILURE(s)) { |
|
1696 return NW_STAT_FAILURE; |
|
1697 } |
|
1698 } |
|
1699 break; |
|
1700 } |
|
1701 return NW_STAT_FAILURE; |
|
1702 } |
|
1703 return NW_STAT_SUCCESS; |
|
1704 } |
|
1705 |
|
1706 /* Assumes position is at '<' on entry. */ |
|
1707 static |
|
1708 NW_Status_t |
|
1709 NW_XML_Parse_ElementConsume(NW_XML_Reader_t* pT, |
|
1710 const struct NW_XML_Parser_EventCallbacks_s* pE, |
|
1711 const RPointerArray <CXML_Internal_Entity_t>* internalEntityList) |
|
1712 { |
|
1713 /* |
|
1714 [39] element ::= EmptyElemTag | STag content ETag |
|
1715 |
|
1716 [40] STag ::= '<' Name (S Attribute)* S? '>' |
|
1717 |
|
1718 [41] Attribute ::= Name Eq AttValue |
|
1719 |
|
1720 [42] ETag ::= '</' Name S? '>' |
|
1721 |
|
1722 [43] content ::= CharData? |
|
1723 ((element | Reference | CDSect | PI | Comment) |
|
1724 CharData?)* |
|
1725 |
|
1726 [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>' |
|
1727 */ |
|
1728 NW_Status_t s; |
|
1729 NW_Uint32 match; |
|
1730 NW_Uint32 isEmptyElement; |
|
1731 NW_Uint32 nestingCount; |
|
1732 NW_Uint32 inContent; |
|
1733 NW_Uint32 prevIndex; |
|
1734 NW_Uint32 prevCharIndex; |
|
1735 CXML_Uint8* intEntityValStr = NULL; |
|
1736 NW_Uint32 contentLen = 0; |
|
1737 NW_XML_Reader_LineColumn_t prevLineColumn; |
|
1738 NW_Bool entityFoundLevel_2 = NW_FALSE; |
|
1739 NW_XML_Reader_Interval_t I_elementContent; |
|
1740 NW_XML_Reader_Interval_Init(&I_elementContent); |
|
1741 |
|
1742 |
|
1743 s = NW_XML_Reader_SkipSpace(pT); |
|
1744 if (NW_STAT_IS_FAILURE(s)) |
|
1745 { |
|
1746 return NW_STAT_FAILURE; |
|
1747 } |
|
1748 |
|
1749 /* Look for initial element markup. */ |
|
1750 s = NW_XML_Parse_ElementOpeningMarkupConsume(pT, &isEmptyElement, pE, internalEntityList); |
|
1751 if (NW_STAT_IS_FAILURE(s)) { |
|
1752 return NW_STAT_FAILURE; |
|
1753 } |
|
1754 if (isEmptyElement) { |
|
1755 return NW_STAT_SUCCESS; |
|
1756 } |
|
1757 inContent = 0; |
|
1758 for (nestingCount = 1; nestingCount;) { |
|
1759 /* test for ETag */ |
|
1760 s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_EndTagStartLength, |
|
1761 NW_XML_String_EndTagStart, &match); |
|
1762 if (NW_STAT_IS_FAILURE(s)) { |
|
1763 return NW_STAT_FAILURE; |
|
1764 } |
|
1765 if (match) |
|
1766 { |
|
1767 NW_XML_Reader_Interval_t I_name; |
|
1768 if (inContent) |
|
1769 { |
|
1770 inContent = 0; |
|
1771 NW_XML_Reader_Interval_Stop(&I_elementContent, pT); |
|
1772 |
|
1773 /*Write the contents only if I_elementContent have some contents*/ |
|
1774 |
|
1775 if(NW_XML_Reader_Interval_IsWellFormed(&I_elementContent) ) |
|
1776 { |
|
1777 if (pE->Content_CB != NULL) |
|
1778 { |
|
1779 s = (*(pE->Content_CB))(pT, &I_elementContent, pE->pClientPointer); |
|
1780 if (NW_STAT_IS_FAILURE(s)) { |
|
1781 return NW_STAT_FAILURE; |
|
1782 } |
|
1783 }/*end if (pE->Content_CB != NULL)*/ |
|
1784 } |
|
1785 }/*end if(inContent)*/ |
|
1786 |
|
1787 s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_EndTagStartLength); |
|
1788 if (NW_STAT_IS_FAILURE(s)) { |
|
1789 return NW_STAT_FAILURE; |
|
1790 } |
|
1791 /* Name */ |
|
1792 s = NW_XML_Parse_NameConsume(pT, &I_name, &match); |
|
1793 if (NW_STAT_IS_FAILURE(s) || !match) { |
|
1794 return NW_STAT_FAILURE; |
|
1795 } |
|
1796 /* S */ |
|
1797 s = NW_XML_Reader_SkipSpace(pT); |
|
1798 if (NW_STAT_IS_FAILURE(s)) { |
|
1799 return NW_STAT_FAILURE; |
|
1800 } |
|
1801 /* '>' */ |
|
1802 s = NW_XML_Reader_AsciiCharMatch(pT, '>', &match); |
|
1803 if (NW_STAT_IS_FAILURE(s) || !match) { |
|
1804 return NW_STAT_FAILURE; |
|
1805 } |
|
1806 s = NW_XML_Reader_Advance(pT); |
|
1807 if (NW_STAT_IS_FAILURE(s)) { |
|
1808 return NW_STAT_FAILURE; |
|
1809 } |
|
1810 /* FUTURE could check that Etag name matches STag name */ |
|
1811 nestingCount--; |
|
1812 if (pE->Tag_End_CB != NULL) { |
|
1813 s = (*(pE->Tag_End_CB))(pT, &I_name, |
|
1814 0, /* not empty tag */ |
|
1815 pE->pClientPointer); |
|
1816 if (NW_STAT_IS_FAILURE(s)) { |
|
1817 return NW_STAT_FAILURE; |
|
1818 } |
|
1819 /*Just now element (tag) is consumned so contenst will start |
|
1820 *after this. So, init the content pointer. |
|
1821 */ |
|
1822 |
|
1823 NW_XML_Reader_Interval_Start(&I_elementContent, pT); |
|
1824 } |
|
1825 continue; |
|
1826 } /*end if(match) */ |
|
1827 |
|
1828 |
|
1829 /* test for PI */ |
|
1830 s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_PiFormStartLength, |
|
1831 NW_XML_String_PiFormStart, &match); |
|
1832 if (NW_STAT_IS_FAILURE(s)) { |
|
1833 return NW_STAT_FAILURE; |
|
1834 } |
|
1835 if (match) { |
|
1836 NW_PiFormTypeTag_t pi_type; |
|
1837 NW_XML_Reader_Interval_t I_name, I_version, I_encoding, I_standalone; |
|
1838 NW_XML_Reader_Interval_t I_content; |
|
1839 NW_Uint32 nameValid, versionValid, encodingValid, standaloneValid; |
|
1840 NW_Uint32 contentValid; |
|
1841 if (inContent) { |
|
1842 inContent = 0; |
|
1843 NW_XML_Reader_Interval_Stop(&I_elementContent, pT); |
|
1844 if (pE->Content_CB != NULL) { |
|
1845 s = (*(pE->Content_CB))(pT, &I_elementContent, pE->pClientPointer); |
|
1846 if (NW_STAT_IS_FAILURE(s)) { |
|
1847 return NW_STAT_FAILURE; |
|
1848 } |
|
1849 } |
|
1850 } |
|
1851 s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_PiFormStartLength); |
|
1852 if (NW_STAT_IS_FAILURE(s)) { |
|
1853 return NW_STAT_FAILURE; |
|
1854 } |
|
1855 s = NW_XML_Parse_PiFormConsume(pT, &pi_type, |
|
1856 &nameValid, |
|
1857 &I_name, |
|
1858 &versionValid, |
|
1859 &I_version, |
|
1860 &encodingValid, |
|
1861 &I_encoding, |
|
1862 &standaloneValid, |
|
1863 &I_standalone, |
|
1864 &contentValid, |
|
1865 &I_content, |
|
1866 internalEntityList); |
|
1867 if (NW_STAT_IS_FAILURE(s) || !nameValid) { |
|
1868 return NW_STAT_FAILURE; |
|
1869 } |
|
1870 if (pi_type == PI && (pE->PiForm_CB != NULL)) { |
|
1871 s = (*(pE->PiForm_CB))(pT, pi_type, |
|
1872 (nameValid ? &I_name : NULL), |
|
1873 (versionValid ? &I_version : NULL), |
|
1874 (encodingValid ? &I_encoding : NULL), |
|
1875 (standaloneValid ? &I_standalone : NULL), |
|
1876 (contentValid ? &I_content : NULL), |
|
1877 pE->pClientPointer); |
|
1878 if (NW_STAT_IS_FAILURE(s)) { |
|
1879 return NW_STAT_FAILURE; |
|
1880 } |
|
1881 } |
|
1882 if (pi_type != PI) { |
|
1883 /* BUG is this correct? */ |
|
1884 return NW_STAT_FAILURE; |
|
1885 } |
|
1886 continue; |
|
1887 } |
|
1888 /* test for Comment */ |
|
1889 s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_CommentStartLength, |
|
1890 NW_XML_String_CommentStart, &match); |
|
1891 if (NW_STAT_IS_FAILURE(s)) { |
|
1892 return NW_STAT_FAILURE; |
|
1893 } |
|
1894 if (match) { |
|
1895 NW_XML_Reader_Interval_t I_comment; |
|
1896 if (inContent) { |
|
1897 inContent = 0; |
|
1898 NW_XML_Reader_Interval_Stop(&I_elementContent, pT); |
|
1899 if (pE->Content_CB != NULL) { |
|
1900 s = (*(pE->Content_CB))(pT, &I_elementContent, pE->pClientPointer); |
|
1901 if (NW_STAT_IS_FAILURE(s)) { |
|
1902 return NW_STAT_FAILURE; |
|
1903 } |
|
1904 } |
|
1905 } |
|
1906 s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_CommentStartLength); |
|
1907 if (NW_STAT_IS_FAILURE(s)) { |
|
1908 return NW_STAT_FAILURE; |
|
1909 } |
|
1910 s = NW_XML_Parse_CommentConsume(pT, &I_comment, pE); |
|
1911 if (NW_STAT_IS_FAILURE(s)) { |
|
1912 return NW_STAT_FAILURE; |
|
1913 } |
|
1914 continue; |
|
1915 } |
|
1916 /* test for CDSect */ |
|
1917 s = NW_XML_Reader_AsciiStringMatch(pT, NW_XML_String_CdataStartLength, |
|
1918 NW_XML_String_CdataStart, &match); |
|
1919 if (NW_STAT_IS_FAILURE(s)) { |
|
1920 return NW_STAT_FAILURE; |
|
1921 } |
|
1922 if (match) { |
|
1923 NW_XML_Reader_Interval_t I_cdata; |
|
1924 if (inContent) { |
|
1925 inContent = 0; |
|
1926 NW_XML_Reader_Interval_Stop(&I_elementContent, pT); |
|
1927 if (pE->Content_CB != NULL) { |
|
1928 s = (*(pE->Content_CB))(pT, &I_elementContent, pE->pClientPointer); |
|
1929 if (NW_STAT_IS_FAILURE(s)) { |
|
1930 return NW_STAT_FAILURE; |
|
1931 } |
|
1932 } |
|
1933 } |
|
1934 s = NW_XML_Reader_AdvanceOffset(pT, NW_XML_String_CdataStartLength); |
|
1935 if (NW_STAT_IS_FAILURE(s)) { |
|
1936 return NW_STAT_FAILURE; |
|
1937 } |
|
1938 NW_XML_Reader_Interval_Start(&I_cdata, pT); |
|
1939 for (;;) { |
|
1940 s = NW_XML_Reader_AsciiStringMatch(pT, |
|
1941 NW_XML_String_CdataEndLength, |
|
1942 NW_XML_String_CdataEnd, |
|
1943 &match); |
|
1944 if (NW_STAT_IS_FAILURE(s)) { |
|
1945 NW_XML_Reader_Interval_Stop(&I_cdata, pT); |
|
1946 return NW_STAT_FAILURE; |
|
1947 } |
|
1948 if (match) { |
|
1949 NW_XML_Reader_Interval_Stop(&I_cdata, pT); |
|
1950 s = NW_XML_Reader_AdvanceOffset(pT, |
|
1951 NW_XML_String_CdataEndLength); |
|
1952 if (NW_STAT_IS_FAILURE(s)) { |
|
1953 return NW_STAT_FAILURE; |
|
1954 } |
|
1955 /* BUG Is this spec compliant parsing of CDATA? */ |
|
1956 if (pE->Cdata_CB != NULL) { |
|
1957 s = (*(pE->Cdata_CB))(pT, &I_cdata, pE->pClientPointer); |
|
1958 if (NW_STAT_IS_FAILURE(s)) { |
|
1959 return NW_STAT_FAILURE; |
|
1960 } |
|
1961 } |
|
1962 break; |
|
1963 } |
|
1964 s = NW_XML_Reader_Advance(pT); |
|
1965 if (NW_STAT_IS_FAILURE(s)) { |
|
1966 NW_XML_Reader_Interval_Stop(&I_cdata, pT); |
|
1967 return NW_STAT_FAILURE; |
|
1968 } |
|
1969 } |
|
1970 continue; |
|
1971 } |
|
1972 /* test for illegal '<' or nested element */ |
|
1973 s = NW_XML_Reader_AsciiCharMatch(pT, '<', &match); |
|
1974 if (NW_STAT_IS_FAILURE(s)) { |
|
1975 return NW_STAT_FAILURE; |
|
1976 } |
|
1977 if (match) { |
|
1978 if (inContent) { |
|
1979 inContent = 0; |
|
1980 NW_XML_Reader_Interval_Stop(&I_elementContent, pT); |
|
1981 |
|
1982 if (pE->Content_CB != NULL) |
|
1983 { |
|
1984 contentLen = I_elementContent.stop - I_elementContent.start; |
|
1985 if(contentLen > 0) |
|
1986 { |
|
1987 s = (*(pE->Content_CB))(pT, &I_elementContent, pE->pClientPointer); |
|
1988 if (NW_STAT_IS_FAILURE(s)) |
|
1989 { |
|
1990 return NW_STAT_FAILURE; |
|
1991 } |
|
1992 }//end if(contentLen > 0) |
|
1993 }// end if(pE->Content_CB != NULL) |
|
1994 } |
|
1995 s = NW_XML_Parse_ElementOpeningMarkupConsume(pT, &isEmptyElement, |
|
1996 pE, internalEntityList); |
|
1997 if (NW_STAT_IS_SUCCESS(s)) { |
|
1998 if (!isEmptyElement) { |
|
1999 nestingCount++; |
|
2000 } |
|
2001 |
|
2002 /*Just now element (tag) is consumned so contenst will start |
|
2003 *after this. So, init the content pointer. |
|
2004 */ |
|
2005 |
|
2006 NW_XML_Reader_Interval_Start(&I_elementContent, pT); |
|
2007 continue; |
|
2008 } |
|
2009 return NW_STAT_FAILURE; |
|
2010 } |
|
2011 |
|
2012 |
|
2013 /* Test for predefined entities and character entries*/ |
|
2014 |
|
2015 s = NW_XML_Reader_AsciiCharMatch(pT, '&', &match); |
|
2016 |
|
2017 if (NW_STAT_IS_FAILURE(s)) |
|
2018 { |
|
2019 return NW_STAT_FAILURE; |
|
2020 } |
|
2021 |
|
2022 |
|
2023 if (match) |
|
2024 { |
|
2025 NW_XML_Reader_Interval_t I_entityData; |
|
2026 NW_Bool entityFoundLevel_1 = NW_FALSE; //If end of entity (;) found |
|
2027 NW_Uint32 entityVal = 0; |
|
2028 NW_XML_Reader_Interval_t* I_content = &I_elementContent; |
|
2029 |
|
2030 //Will back off if not a valid entity |
|
2031 |
|
2032 NW_XML_Reader_GetPosition(pT, |
|
2033 &prevIndex, &prevCharIndex, &prevLineColumn); |
|
2034 |
|
2035 /* If it is here then this must in the contents. The entity can appear |
|
2036 * at the beginning of content. |
|
2037 */ |
|
2038 |
|
2039 inContent = NW_TRUE; |
|
2040 entityFoundLevel_2 = NW_FALSE; |
|
2041 NW_XML_Reader_Interval_Stop(I_content, pT); //Contents before entity |
|
2042 |
|
2043 s = CXML_XML_Parser_Entity(pT,&I_entityData,&entityFoundLevel_1); |
|
2044 |
|
2045 if (NW_STAT_IS_FAILURE(s)) |
|
2046 { |
|
2047 return NW_STAT_FAILURE; |
|
2048 } |
|
2049 |
|
2050 if (entityFoundLevel_1 && inContent) |
|
2051 { |
|
2052 //Validate the entity |
|
2053 |
|
2054 //The following function checks for the character, |
|
2055 //predefined entities and Internal Entities. |
|
2056 |
|
2057 contentLen = I_entityData.stop - I_entityData.start; |
|
2058 |
|
2059 if(contentLen > 0) |
|
2060 { |
|
2061 s = CXML_XML_Handle_entity(pT, |
|
2062 &I_entityData,&entityVal, |
|
2063 &intEntityValStr,&entityFoundLevel_2, |
|
2064 (void*) internalEntityList); |
|
2065 } |
|
2066 else |
|
2067 { |
|
2068 //Not a valid entity e.g. "&&;" test case |
|
2069 entityFoundLevel_2 = NW_FALSE; |
|
2070 } |
|
2071 |
|
2072 if (NW_STAT_IS_FAILURE(s)) |
|
2073 { |
|
2074 return NW_STAT_FAILURE; |
|
2075 } |
|
2076 |
|
2077 if(entityFoundLevel_2 == CXML_TRUE) |
|
2078 { |
|
2079 inContent = NW_FALSE; |
|
2080 |
|
2081 //Now write content before entity first |
|
2082 |
|
2083 |
|
2084 if (pE->Content_CB != NULL) { |
|
2085 contentLen = I_content->stop - I_content->start; |
|
2086 if(contentLen > 0) |
|
2087 { |
|
2088 s = (*(pE->Content_CB))(pT, I_content, pE->pClientPointer); |
|
2089 if (NW_STAT_IS_FAILURE(s)) { |
|
2090 return NW_STAT_FAILURE; |
|
2091 } |
|
2092 } |
|
2093 } |
|
2094 |
|
2095 // Write the entity content now. There are two possibilities for |
|
2096 // entities. |
|
2097 // |
|
2098 // 1) If it is character or decimal or predefined entities. |
|
2099 // In this case, intEntityValStr = NULL. |
|
2100 // |
|
2101 // 2) If it is "Internal Entity" then intEntityValStr != NULL. |
|
2102 // So, this is directly written to WBXML encoder as inline string. |
|
2103 // In this case, entityVal = 0; |
|
2104 |
|
2105 |
|
2106 if (pE->Entity_CB != NULL ) |
|
2107 { |
|
2108 s = (*(pE->Entity_CB))(pT, entityVal, pE->pClientPointer,intEntityValStr); |
|
2109 |
|
2110 if(intEntityValStr != NULL) |
|
2111 { |
|
2112 NW_Mem_Free(intEntityValStr); |
|
2113 } |
|
2114 if (NW_STAT_IS_FAILURE(s)) |
|
2115 { |
|
2116 return NW_STAT_FAILURE; |
|
2117 } |
|
2118 |
|
2119 }/*end if(pE->Entity_CB != NULL) */ |
|
2120 }//endif(entityFoundLevel_2 == CXML_TRUE) |
|
2121 else |
|
2122 { |
|
2123 //No valid entity found. Parse as the normal string |
|
2124 NW_XML_Reader_SetPosition(pT, |
|
2125 prevIndex, |
|
2126 prevCharIndex, |
|
2127 &prevLineColumn); |
|
2128 } |
|
2129 } //end if (entityFoundLevel_1 && inContent) |
|
2130 else |
|
2131 { |
|
2132 //No valid entity found. Parse as the normal string |
|
2133 |
|
2134 NW_XML_Reader_SetPosition(pT, |
|
2135 prevIndex, |
|
2136 prevCharIndex, |
|
2137 &prevLineColumn); |
|
2138 } |
|
2139 } //end match |
|
2140 |
|
2141 |
|
2142 /* BUG no reference parsing and also permits illegal char data */ |
|
2143 if (!inContent) |
|
2144 { |
|
2145 NW_XML_Reader_Interval_Start(&I_elementContent, pT); |
|
2146 inContent = 1; |
|
2147 if(entityFoundLevel_2 == NW_TRUE) |
|
2148 { |
|
2149 //Don't advance if it is entity as we did already |
|
2150 entityFoundLevel_2 = NW_FALSE; |
|
2151 continue; |
|
2152 } |
|
2153 } |
|
2154 |
|
2155 s = NW_XML_Reader_Advance(pT); |
|
2156 if (NW_STAT_IS_FAILURE(s)) { |
|
2157 return NW_STAT_FAILURE; |
|
2158 } |
|
2159 }/*end for(..) */ |
|
2160 return NW_STAT_SUCCESS; |
|
2161 } |
|
2162 |
|
2163 EXPORT_C NW_Status_t |
|
2164 NW_XML_Parse(NW_XML_Reader_t* pT, const struct NW_XML_Parser_EventCallbacks_s* pE) |
|
2165 { |
|
2166 /* |
|
2167 [1] document ::= prolog element Misc* |
|
2168 */ |
|
2169 NW_Status_t s = NW_STAT_SUCCESS; |
|
2170 RPointerArray <CXML_Internal_Entity_t> internalEntityList; |
|
2171 |
|
2172 if (pE->StartDocument_CB != NULL) { |
|
2173 s = (*(pE->StartDocument_CB))(pT, pE->pClientPointer); |
|
2174 if (NW_STAT_IS_FAILURE(s)) { |
|
2175 s = NW_STAT_FAILURE; |
|
2176 goto nw_xml_parser_final; |
|
2177 } |
|
2178 } |
|
2179 |
|
2180 s = NW_XML_Parse_PrologConsume(pT, pE,&internalEntityList); |
|
2181 if (NW_STAT_IS_FAILURE(s)) { |
|
2182 s = NW_STAT_FAILURE; |
|
2183 goto nw_xml_parser_final; |
|
2184 } |
|
2185 |
|
2186 s = NW_XML_Parse_ElementConsume(pT, pE, &internalEntityList); |
|
2187 if (NW_STAT_IS_FAILURE(s)) { |
|
2188 s = NW_STAT_FAILURE; |
|
2189 goto nw_xml_parser_final; |
|
2190 } |
|
2191 |
|
2192 s = NW_XML_Parse_MiscConsume(pT, pE, &internalEntityList); |
|
2193 if (NW_STAT_IS_FAILURE(s) && !NW_XML_Reader_AtEnd(pT)) { |
|
2194 s = NW_STAT_FAILURE; |
|
2195 goto nw_xml_parser_final; |
|
2196 } |
|
2197 |
|
2198 if (!NW_XML_Reader_AtEnd(pT)) { |
|
2199 s = NW_STAT_FAILURE; |
|
2200 goto nw_xml_parser_final; |
|
2201 } |
|
2202 |
|
2203 if (pE->EndDocument_CB != NULL) { |
|
2204 s = (*(pE->EndDocument_CB))(pT, pE->pClientPointer); |
|
2205 if (NW_STAT_IS_FAILURE(s)) { |
|
2206 goto nw_xml_parser_final; |
|
2207 } |
|
2208 } |
|
2209 |
|
2210 nw_xml_parser_final: |
|
2211 |
|
2212 CXML_XML_Parser_Free_I_Entity_List(internalEntityList); |
|
2213 return s; |
|
2214 } |
|
2215 |
|