|
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 |
|
19 /***************************************************************** |
|
20 ** File: wbxml_parse_logic.c |
|
21 ** |
|
22 ** Description: |
|
23 * |
|
24 * Here is the main parser logic. None of these functions has |
|
25 * any knowlege of how wbxml is stored or read, so they should |
|
26 * work as well with a buffer, stream or file based parser. These |
|
27 * functions require some implementation of the "parser reader |
|
28 * interface" as defined in wbxml_reader.h. |
|
29 * |
|
30 *****************************************************************/ |
|
31 |
|
32 #include "cxml_internal.h" |
|
33 #include <xml/cxml/nw_wbxml_token.h> |
|
34 #include <xml/cxml/nw_wbxml_dictionary.h> |
|
35 #include <xml/cxml/nw_wbxml_document.h> |
|
36 #include <xml/cxml/nw_wbxml_event.h> |
|
37 #include <xml/cxml/nw_wbxml_reader.h> |
|
38 #include "nw_wbxml_parsei.h" |
|
39 #include <xml/cxml/nw_string_char.h> |
|
40 |
|
41 #ifndef HTTP_utf_8 |
|
42 #define HTTP_utf_8 0x6A |
|
43 #endif |
|
44 |
|
45 #define TOKEN_STATE_TAG 0 |
|
46 #define TOKEN_STATE_ATTR 1 |
|
47 |
|
48 #define WBXML_MAX_RECURSIVE_CALL_DEPTH 120 /* For parse element only */ |
|
49 |
|
50 /* The parser tries to be very strict about errors caused by bad NW_Byte |
|
51 * code, lack of memory, etc. For example, the parser will not read |
|
52 * past the end of the buffer. Callbacks can also set error status to |
|
53 * stop parsing. These will be detected as soon as possible after the |
|
54 * callback returns. The following method is called with the return |
|
55 * value (NW_Status_t) from the callback functions. The status is |
|
56 * saved and if it is not NW_STAT_SUCCESS, then the parser's flags |
|
57 * field is updated so that the parser will know that a callback has |
|
58 * raised an exception/error condition. The parser will quit as soon |
|
59 * as it checks the flags. |
|
60 */ |
|
61 |
|
62 static void |
|
63 NW_WBXML_Parser_setStatus (NW_WBXML_Parser_t * parser, |
|
64 NW_Status_t status) |
|
65 { |
|
66 parser->status = status; |
|
67 |
|
68 switch (status) |
|
69 { |
|
70 case NW_STAT_SUCCESS: |
|
71 break; |
|
72 case NW_STAT_OUT_OF_MEMORY: |
|
73 parser->flags |= NW_WBXML_PARSER_NOMEMORY; |
|
74 break; |
|
75 case NW_STAT_WBXML_ERROR_BYTECODE: |
|
76 parser->flags |= NW_WBXML_PARSER_BYTECODEERROR; |
|
77 break; |
|
78 case NW_STAT_WBXML_ERROR_CHARSET_UNSUPPORTED: |
|
79 parser->flags |= NW_WBXML_PARSER_CHARSET_UNSUPPORTED; |
|
80 break; |
|
81 default: |
|
82 parser->flags |= NW_WBXML_PARSER_UNKNOWN_ERROR; |
|
83 break; |
|
84 } |
|
85 return; |
|
86 } |
|
87 |
|
88 /* |
|
89 * Convert the parser's flag status code to a NW_Status_t constant |
|
90 */ |
|
91 |
|
92 static NW_Status_t |
|
93 NW_WBXML_Parser_flagToStatus (NW_WBXML_Parser_t * parser) |
|
94 { |
|
95 if (parser->flags & NW_WBXML_PARSER_NOMEMORY) |
|
96 return NW_STAT_OUT_OF_MEMORY; |
|
97 |
|
98 if (parser->flags & NW_WBXML_PARSER_BYTECODEERROR) |
|
99 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
100 |
|
101 if (parser->flags & NW_WBXML_PARSER_CHARSET_UNSUPPORTED) |
|
102 return NW_STAT_WBXML_ERROR_CHARSET_UNSUPPORTED; |
|
103 |
|
104 return parser->status; |
|
105 } |
|
106 |
|
107 |
|
108 #define GET_STATE(parser) ((parser)->state & NW_WBXML_PARSER_S_MASK) |
|
109 #define SET_STATE(parser, st) \ |
|
110 ((parser)->state = (~NW_WBXML_PARSER_S_MASK & parser->state) | (st)) |
|
111 |
|
112 #define CHECK_PARSER_STATUS \ |
|
113 if((parser->flags & NW_WBXML_PARSER_S_MASK) != NW_WBXML_PARSER_OK) \ |
|
114 return NW_WBXML_Parser_flagToStatus(parser) |
|
115 |
|
116 |
|
117 /* |
|
118 * Create an uninitialized code page registry. As long as the registry is not |
|
119 * created, it will be ignored. Once it has been created, the parser will check |
|
120 * the REGISTRY_INIT flag. If this is not set, the registry will be initialized |
|
121 * as the parser runs. If this is set, then the registry will be consulted when |
|
122 * updating the offset. |
|
123 */ |
|
124 |
|
125 NW_Status_t |
|
126 NW_WBXML_Parser_addCPRegistry(NW_WBXML_Parser_t* parser, |
|
127 NW_WBXML_CP_Registry_Entry_t* storage, |
|
128 NW_Int32 count) |
|
129 { |
|
130 NW_ASSERT(parser != NULL); |
|
131 NW_ASSERT(storage != NULL); |
|
132 |
|
133 parser->cp_registry.storage = storage; |
|
134 parser->cp_registry.current = storage; |
|
135 parser->cp_registry.count = count; |
|
136 // WLIU_DEBUG: parser->cp_registry.realcount = 0; |
|
137 parser->state &= ~NW_WBXML_REGISTRY_INIT; /* Make sure flag is not set */ |
|
138 return NW_STAT_SUCCESS; |
|
139 } |
|
140 |
|
141 static void |
|
142 NW_WBXML_CPRegistry_addEntry(NW_WBXML_CP_Registry_t *registry , |
|
143 NW_Uint8 code_page, |
|
144 NW_Uint32 offset, /* must point to switch_page token */ |
|
145 NW_Uint8 token_state) |
|
146 { |
|
147 NW_ASSERT(registry != NULL); |
|
148 NW_ASSERT(registry->current < (registry->storage + registry->count)); |
|
149 |
|
150 /* ignoring page type (tag or attribute) check that registry is in |
|
151 increasing order of offset so that the algorith in |
|
152 NW_WBXML_CPRegistry_getCodePages() works */ |
|
153 NW_ASSERT((registry->current > registry->storage) ? |
|
154 (offset > (registry->current - 1)->start_offset) |
|
155 : 1); |
|
156 /* Each entry must record if it is for tokens or attributes. A |
|
157 trick to encode this without extra memory relies on the use of two |
|
158 bytes in WBXML to encode a page switch. With two bytes one has an |
|
159 even offset and one an odd offset. We pick the even if it is a tag |
|
160 page and the odd offset if it is an attribute page. */ |
|
161 if (token_state == TOKEN_STATE_TAG) { |
|
162 if (offset & 1) { /* if it is odd, advance one to make it even */ |
|
163 offset++; |
|
164 } |
|
165 } else { |
|
166 NW_ASSERT(token_state == TOKEN_STATE_ATTR); |
|
167 if ((offset & 1) == 0) { /* if it is even, advance one to make it odd */ |
|
168 offset++; |
|
169 } |
|
170 } |
|
171 registry->current->start_offset = offset; |
|
172 registry->current->code_page = code_page; |
|
173 |
|
174 //if(registry->current < (registry->storage + registry->count - 1)){ |
|
175 registry->current++; |
|
176 // WLIU_DEBUG: registry->realcount++; |
|
177 // |
|
178 } |
|
179 |
|
180 void |
|
181 NW_WBXML_CPRegistry_getCodePages(NW_WBXML_CP_Registry_t* registry, |
|
182 NW_Uint32 offset, |
|
183 NW_Uint8 *tag_code_page, |
|
184 NW_Uint8 *attribute_code_page) |
|
185 { |
|
186 NW_WBXML_CP_Registry_Entry_t* entry; |
|
187 |
|
188 NW_ASSERT(registry != NULL); |
|
189 |
|
190 *tag_code_page = 0; |
|
191 *attribute_code_page = 0; |
|
192 for (entry = registry->storage; |
|
193 entry < (registry->storage + registry->count); |
|
194 entry++){ |
|
195 /* assume that the entries are in increasing offset order */ |
|
196 NW_ASSERT((entry > registry->storage) ? |
|
197 (entry->start_offset > (entry - 1)->start_offset) |
|
198 : 1); |
|
199 |
|
200 if(offset > entry->start_offset) { |
|
201 if(entry->start_offset & 1) { |
|
202 /* odd offset indicates attributes */ |
|
203 *attribute_code_page = entry->code_page; |
|
204 } else { |
|
205 /* even offset indicates tokens */ |
|
206 *tag_code_page = entry->code_page; |
|
207 } |
|
208 } else { |
|
209 break; /* early out */ |
|
210 } |
|
211 } |
|
212 } |
|
213 |
|
214 |
|
215 /* |
|
216 This function parses "version publicid charset strtbl" which is a |
|
217 sequence that comprises the "header" of a WBXML document. |
|
218 |
|
219 From specification WAP-192-WBXML-20010725-a, Version 1.3, 25 July 2001, |
|
220 section 5.3 BNF for Document Structure: |
|
221 |
|
222 start = version publicid charset strtbl body |
|
223 version = u_int8 // WBXML version number |
|
224 publicid = mb_u_int32 | ( zero index ) |
|
225 charset = mb_u_int32 |
|
226 strtbl = length *byte |
|
227 length = mb_u_int32 |
|
228 |
|
229 The "version" specifies the WBXML specification version. The |
|
230 version byte contains the major version minus one in the upper |
|
231 four bits and the minor version in the lower four bits. For |
|
232 example, the version number 1.3 would be encoded as 0x03. |
|
233 |
|
234 The first form of publicid is a multi-byte positive integer value, |
|
235 greater than zero, representing a well-known XML document type given |
|
236 an assigned value. See table at section 7.2.1 or try |
|
237 http://www.wapforum.org/wina/wbxml-public-docid.htm |
|
238 Note that 0x01 is used for "unknown or missing public identifier." |
|
239 |
|
240 The second form of publicid begins with a 0 byte followed by a |
|
241 string table index (note that these "index" values are all 0-based |
|
242 byte offsets from the start of the string table). The entry in the |
|
243 string table encodes the XML document type string. |
|
244 |
|
245 The charset is the multi-byte encoding of the IANA charset MIBenum |
|
246 http://www.iana.org/assignments/character-sets |
|
247 |
|
248 The string table either has length 0, if empty, or the length is the |
|
249 byte count of the string table block not counting the length byte |
|
250 itself. |
|
251 |
|
252 This is what the specification says about "index" as an index into |
|
253 the string table: |
|
254 |
|
255 "Various tokens encode references to the contents of the string |
|
256 table. These references are encoded as scalar byte offsets from the |
|
257 first byte of the first string in the string table. For example, the |
|
258 offset of the first string is zero (0)." |
|
259 |
|
260 So, "index" is a 0-based byte offset from the first byte of the |
|
261 string table. The first byte of the string table is the one after |
|
262 the multi-byte encoding of the string table length. |
|
263 |
|
264 This function returns one of: |
|
265 |
|
266 NW_STAT_SUCCESS |
|
267 NW_STAT_OUT_OF_MEMORY |
|
268 NW_STAT_WBXML_ERROR_BYTECODE |
|
269 */ |
|
270 NW_Status_t |
|
271 NW_WBXML_Parser_docHeaderParse(NW_WBXML_Parser_t* pParser, |
|
272 NW_WBXML_Document_t* pDoc) |
|
273 { |
|
274 NW_Int32 bytesRead; |
|
275 NW_Uint32 docTypeByteOffset = 0; |
|
276 NW_Status_t substatus; |
|
277 NW_Status_t status = NW_STAT_WBXML_ERROR_BYTECODE; |
|
278 |
|
279 /* this is an internal function where caller should guarantee these */ |
|
280 NW_ASSERT(pParser != NULL); |
|
281 NW_ASSERT(pDoc != NULL); |
|
282 NW_ASSERT(GET_STATE(pParser) == NW_WBXML_PARSER_S_START); |
|
283 |
|
284 /* version */ |
|
285 pDoc->version = NW_WBXML_Parser_readUint8(pParser); |
|
286 if (NW_WBXML_Parser_advance(pParser, 1) < 0) { |
|
287 goto errorExitHeaderParse; |
|
288 } |
|
289 /* publicid */ |
|
290 bytesRead = NW_WBXML_Parser_readMbUint32(pParser, &(pDoc->publicid)); |
|
291 if ((bytesRead < 0) |
|
292 || (NW_WBXML_Parser_advance(pParser, bytesRead) < 0)) { |
|
293 goto errorExitHeaderParse; |
|
294 } |
|
295 /* check for publicid second form referencing string table */ |
|
296 if (pDoc->publicid == 0) { |
|
297 /* save doctype string table index for after string table is read */ |
|
298 bytesRead = NW_WBXML_Parser_readMbUint32(pParser, &docTypeByteOffset); |
|
299 if ((bytesRead < 0) |
|
300 || (NW_WBXML_Parser_advance(pParser, bytesRead) < 0)) { |
|
301 goto errorExitHeaderParse; |
|
302 } |
|
303 } |
|
304 |
|
305 if(pDoc->publicid == 1) //As per WBXML spec, invalid public identifier |
|
306 { |
|
307 return NW_STAT_WMLBROWSER_BAD_CONTENT; |
|
308 } |
|
309 |
|
310 /* charset */ |
|
311 if (pDoc->version != 0) { |
|
312 bytesRead = NW_WBXML_Parser_readMbUint32(pParser, &(pDoc->charset)); |
|
313 if ((bytesRead < 0) |
|
314 || (NW_WBXML_Parser_advance(pParser, bytesRead) < 0)) { |
|
315 goto errorExitHeaderParse; |
|
316 } |
|
317 } else { |
|
318 /* For WBXML version 1.0, which did not have a charset field in |
|
319 the document header, we hardwire the charset to UTF-8. This is |
|
320 against the spec which says that the charset should come as |
|
321 side info with the doc (e.g., get charset from the load |
|
322 response), but the API needs to change to support this so |
|
323 rather than reject all version 1.0 docs we accept the UTF-8 |
|
324 (includes ASCII but not Latin-1) encoded ones. */ |
|
325 pDoc->charset = HTTP_utf_8; |
|
326 } |
|
327 substatus = NW_String_charsetValid(pDoc->charset); |
|
328 if (substatus != NW_STAT_SUCCESS) { |
|
329 status = substatus; |
|
330 goto errorExitHeaderParse; |
|
331 } |
|
332 /* strtbl */ |
|
333 substatus = NW_WBXML_Parser_readStringTable(pParser, pDoc, |
|
334 &(pDoc->strtbl.data)); |
|
335 if (substatus != NW_STAT_SUCCESS) { |
|
336 status = substatus; |
|
337 goto errorExitHeaderParse; |
|
338 } |
|
339 |
|
340 /* record remainder of doc as the body length */ |
|
341 pDoc->body_len = pParser->left; |
|
342 |
|
343 /* deal with doctype string, maybe from string table */ |
|
344 |
|
345 if(pDoc->doc_type) |
|
346 { |
|
347 NW_String_delete(pDoc->doc_type); |
|
348 } |
|
349 |
|
350 pDoc->doc_type = NULL; |
|
351 if (pDoc->publicid == 0) { |
|
352 /* now that we have the string table, get the doctype string */ |
|
353 if ((docTypeByteOffset >= pDoc->strtbl.length) |
|
354 || (!NW_String_valid(pDoc->strtbl.data + docTypeByteOffset, |
|
355 pDoc->strtbl.length - docTypeByteOffset, |
|
356 pDoc->charset))) { |
|
357 goto errorExitHeaderParse; |
|
358 } |
|
359 pDoc->doc_type = NW_String_new(); |
|
360 if (pDoc->doc_type != NULL) { |
|
361 if (NW_String_initialize(pDoc->doc_type, |
|
362 pDoc->strtbl.data + docTypeByteOffset, |
|
363 pDoc->charset) != NW_STAT_SUCCESS) { |
|
364 NW_String_delete(pDoc->doc_type); |
|
365 pDoc->doc_type = NULL; |
|
366 goto errorExitHeaderParse; |
|
367 } |
|
368 /* TBD should now go back and try to fill in the internal "publicId" |
|
369 from the WBXML dictionary to match the docType. */ |
|
370 } else { |
|
371 status = NW_STAT_OUT_OF_MEMORY; |
|
372 goto errorExitHeaderParse; |
|
373 } |
|
374 } else { |
|
375 /* doc came with publicid so now fill in the type string. */ |
|
376 substatus |
|
377 = NW_WBXML_Dictionary_publicId_to_doctypeString(pDoc->publicid, |
|
378 &(pDoc->doc_type)); |
|
379 /* ignore any error other than OOM */ |
|
380 if (substatus == NW_STAT_OUT_OF_MEMORY) { |
|
381 status = NW_STAT_OUT_OF_MEMORY; |
|
382 goto errorExitHeaderParse; |
|
383 } |
|
384 } |
|
385 SET_STATE(pParser, NW_WBXML_PARSER_S_HEADER); |
|
386 pParser->doc = pDoc; |
|
387 status = NW_STAT_SUCCESS; |
|
388 errorExitHeaderParse: |
|
389 return status; |
|
390 } |
|
391 |
|
392 /* |
|
393 * Save/restore context can be used if the parser is to be invoked |
|
394 * reentrantly (in a callback). Normally this should be avoided since |
|
395 * the only really safe way to do this is to save the whole parser |
|
396 * object on the stack. This uses a lot of space! |
|
397 */ |
|
398 |
|
399 NW_Status_t |
|
400 NW_WBXML_Parser_saveContext(NW_WBXML_Parser_t *parser, |
|
401 NW_WBXML_Parser_t *context) |
|
402 { |
|
403 NW_ASSERT(parser != NULL); |
|
404 NW_ASSERT(context != NULL); |
|
405 |
|
406 NW_Mem_memcpy(context, parser, sizeof(*parser)); |
|
407 return NW_STAT_SUCCESS; |
|
408 } |
|
409 |
|
410 NW_Status_t |
|
411 NW_WBXML_Parser_restoreContext(NW_WBXML_Parser_t *parser, |
|
412 NW_WBXML_Parser_t *context) |
|
413 { |
|
414 NW_ASSERT(parser != NULL); |
|
415 NW_ASSERT(context != NULL); |
|
416 |
|
417 NW_Mem_memcpy(parser, context, sizeof(*parser)); |
|
418 return NW_STAT_SUCCESS; |
|
419 } |
|
420 |
|
421 NW_Status_t |
|
422 NW_WBXML_Parser_setTagCodepage(NW_WBXML_Parser_t *parser, |
|
423 NW_Uint8 page) |
|
424 { |
|
425 NW_ASSERT(parser != NULL); |
|
426 |
|
427 parser->tag_code_page = page; |
|
428 return NW_STAT_SUCCESS; |
|
429 } |
|
430 |
|
431 NW_Uint8 |
|
432 NW_WBXML_Parser_getTagCodepage(NW_WBXML_Parser_t *parser) |
|
433 { |
|
434 NW_ASSERT(parser != NULL); |
|
435 |
|
436 return parser->tag_code_page; |
|
437 } |
|
438 |
|
439 NW_Status_t |
|
440 NW_WBXML_Parser_setAttrCodepage(NW_WBXML_Parser_t *parser, |
|
441 NW_Uint8 page) |
|
442 { |
|
443 NW_ASSERT(parser != NULL); |
|
444 |
|
445 parser->attribute_code_page = page; |
|
446 return NW_STAT_SUCCESS; |
|
447 } |
|
448 |
|
449 NW_Uint8 |
|
450 NW_WBXML_Parser_getAttrCodepage(NW_WBXML_Parser_t *parser) |
|
451 { |
|
452 NW_ASSERT(parser != NULL); |
|
453 |
|
454 return parser->attribute_code_page; |
|
455 } |
|
456 |
|
457 /* |
|
458 * Turn an eight bit token into a fully qualified 32 bit token depending |
|
459 * on the parser state. |
|
460 */ |
|
461 |
|
462 static |
|
463 NW_Uint32 |
|
464 FqToken (NW_WBXML_Parser_t * parser, |
|
465 NW_Uint8 token, |
|
466 NW_Int32 token_state) |
|
467 { |
|
468 NW_Uint32 fq_token = token; |
|
469 |
|
470 NW_ASSERT(parser != NULL); |
|
471 |
|
472 fq_token |= (parser->dictionary << 16); |
|
473 if (token_state == TOKEN_STATE_ATTR) { |
|
474 fq_token |= |
|
475 ((parser->attribute_code_page << 8) | NW_WBXML_CP_STATE_ATTR); |
|
476 } else { |
|
477 fq_token |= ((parser->tag_code_page << 8) | NW_WBXML_CP_STATE_TAG); |
|
478 } |
|
479 return fq_token; |
|
480 } |
|
481 |
|
482 |
|
483 /* Invoke callbacks */ |
|
484 |
|
485 /* The callback wrappers use the parser flags to implement an |
|
486 * "exception" mechanism. If a callback returns a non-OK status, the |
|
487 * parser will detect this as soon as possible and stop what |
|
488 * it is doing. |
|
489 */ |
|
490 |
|
491 /* Handle state callbacks */ |
|
492 |
|
493 static |
|
494 void |
|
495 Handle_Pi(NW_WBXML_Parser_t *parser) |
|
496 { |
|
497 NW_Status_t status; |
|
498 if ((parser->handler) && (parser->handler->Pi_CB)){ |
|
499 status = (*(parser->handler->Pi_CB)) (parser, parser->context); |
|
500 NW_WBXML_Parser_setStatus (parser, status); |
|
501 } |
|
502 } |
|
503 |
|
504 static |
|
505 void |
|
506 Handle_Pi_End(NW_WBXML_Parser_t *parser) |
|
507 { |
|
508 NW_Status_t status; |
|
509 if ((parser->handler) && (parser->handler->Pi_End_CB)){ |
|
510 status = (*(parser->handler->Pi_End_CB)) (parser, parser->context); |
|
511 NW_WBXML_Parser_setStatus (parser, status); |
|
512 } |
|
513 } |
|
514 |
|
515 static |
|
516 void |
|
517 Handle_Tag_Start(NW_WBXML_Parser_t *parser) |
|
518 { |
|
519 NW_Status_t status; |
|
520 if ((parser->handler) && (parser->handler->Tag_Start_CB)){ |
|
521 status = (*(parser->handler->Tag_Start_CB)) (parser, parser->context); |
|
522 NW_WBXML_Parser_setStatus (parser, status); |
|
523 } |
|
524 } |
|
525 |
|
526 static |
|
527 void |
|
528 Handle_Tag_End(NW_WBXML_Parser_t *parser) |
|
529 { |
|
530 NW_Status_t status; |
|
531 if ((parser->handler) && (parser->handler->Tag_End_CB)){ |
|
532 status = (*(parser->handler->Tag_End_CB)) (parser, parser->context); |
|
533 NW_WBXML_Parser_setStatus (parser, status); |
|
534 } |
|
535 } |
|
536 |
|
537 static |
|
538 void |
|
539 Handle_Attr_Start(NW_WBXML_Parser_t *parser) |
|
540 { |
|
541 NW_Status_t status; |
|
542 if ((parser->handler) && (parser->handler->Attr_Start_CB)){ |
|
543 status = (*(parser->handler->Attr_Start_CB)) (parser, parser->context); |
|
544 NW_WBXML_Parser_setStatus (parser, status); |
|
545 } |
|
546 } |
|
547 |
|
548 static |
|
549 void |
|
550 Handle_Attr_Val(NW_WBXML_Parser_t *parser) |
|
551 { |
|
552 NW_Status_t status; |
|
553 if ((parser->handler) && (parser->handler->Attr_Val_CB)){ |
|
554 status = (*(parser->handler->Attr_Val_CB)) (parser, parser->context); |
|
555 NW_WBXML_Parser_setStatus (parser, status); |
|
556 } |
|
557 } |
|
558 |
|
559 static |
|
560 void |
|
561 Handle_Content(NW_WBXML_Parser_t *parser) |
|
562 { |
|
563 NW_Status_t status; |
|
564 if ((parser->handler) && (parser->handler->Content_CB)){ |
|
565 status = (*(parser->handler->Content_CB)) (parser, parser->context); |
|
566 NW_WBXML_Parser_setStatus (parser, status); |
|
567 } |
|
568 } |
|
569 |
|
570 static |
|
571 void |
|
572 Handle_Codepage(NW_WBXML_Parser_t *parser) |
|
573 { |
|
574 NW_Status_t status; |
|
575 if ((parser->handler) && (parser->handler->CodePage_CB)){ |
|
576 status = (*(parser->handler->CodePage_CB)) (parser, parser->context); |
|
577 NW_WBXML_Parser_setStatus (parser, status); |
|
578 } |
|
579 } |
|
580 |
|
581 static |
|
582 void |
|
583 Handle_Extension(NW_WBXML_Parser_t *parser) |
|
584 { |
|
585 NW_Status_t status; |
|
586 if ((parser->handler) && (parser->handler->Extension_CB)){ |
|
587 status = (*(parser->handler->Extension_CB)) (parser, parser->context); |
|
588 NW_WBXML_Parser_setStatus (parser, status); |
|
589 } |
|
590 } |
|
591 |
|
592 /* Handle data type callbacks */ |
|
593 |
|
594 static |
|
595 void |
|
596 Handle_Fq_Token(NW_WBXML_Parser_t *parser, |
|
597 NW_Uint32 token) |
|
598 { |
|
599 NW_Status_t status; |
|
600 if ((parser->handler) && (parser->handler->FQToken_CB)){ |
|
601 status = (*(parser->handler->FQToken_CB)) (parser, token, parser->context); |
|
602 NW_WBXML_Parser_setStatus (parser, status); |
|
603 } |
|
604 } |
|
605 |
|
606 static |
|
607 void |
|
608 Handle_Inline_String(NW_WBXML_Parser_t *parser, |
|
609 NW_Uint32 len) |
|
610 { |
|
611 NW_Status_t status; |
|
612 if ((parser->handler) && (parser->handler->InlineString_CB)){ |
|
613 status = (*(parser->handler->InlineString_CB)) (parser, len, |
|
614 parser->context); |
|
615 |
|
616 NW_WBXML_Parser_setStatus (parser, status); |
|
617 } |
|
618 } |
|
619 |
|
620 static |
|
621 void |
|
622 Handle_Table_String(NW_WBXML_Parser_t *parser, |
|
623 NW_Uint32 index) |
|
624 { |
|
625 NW_Status_t status; |
|
626 if ((parser->handler) && (parser->handler->TableString_CB)){ |
|
627 status = (*(parser->handler->TableString_CB)) (parser, index, |
|
628 parser->context); |
|
629 NW_WBXML_Parser_setStatus (parser, status); |
|
630 } |
|
631 } |
|
632 |
|
633 static |
|
634 void |
|
635 Handle_Binary(NW_WBXML_Parser_t *parser, |
|
636 NW_Uint32 value) |
|
637 { |
|
638 NW_Status_t status; |
|
639 if ((parser->handler) && (parser->handler->Binary_CB)){ |
|
640 status = (*(parser->handler->Binary_CB)) (parser, value, parser->context); |
|
641 NW_WBXML_Parser_setStatus (parser, status); |
|
642 } |
|
643 } |
|
644 |
|
645 static |
|
646 void |
|
647 Handle_Opaque(NW_WBXML_Parser_t *parser, |
|
648 NW_Uint32 len) |
|
649 { |
|
650 NW_Status_t status; |
|
651 if ((parser->handler) && (parser->handler->Opaque_CB)){ |
|
652 status = (*(parser->handler->Opaque_CB)) (parser, len, parser->context); |
|
653 NW_WBXML_Parser_setStatus (parser, status); |
|
654 } |
|
655 } |
|
656 |
|
657 static |
|
658 void |
|
659 Handle_Entity(NW_WBXML_Parser_t *parser, |
|
660 NW_Uint32 e) |
|
661 { |
|
662 NW_Status_t status; |
|
663 if ((parser->handler) && (parser->handler->Entity_CB)){ |
|
664 status = (*(parser->handler->Entity_CB)) (parser, e, parser->context); |
|
665 NW_WBXML_Parser_setStatus (parser, status); |
|
666 } |
|
667 } |
|
668 |
|
669 /* |
|
670 * Safely get the next token, checking for switch pages along the way. |
|
671 * While this does advance past any switch pages, it DOES NOT advance |
|
672 * past the returned token. |
|
673 */ |
|
674 |
|
675 static |
|
676 NW_Status_t |
|
677 NW_WBXML_Parser_getNextToken (NW_WBXML_Parser_t * parser, |
|
678 NW_Uint8 * token, |
|
679 NW_Int32 token_state) |
|
680 { |
|
681 |
|
682 NW_ASSERT(parser != NULL); |
|
683 |
|
684 if (!NW_WBXML_Parser_hasMoreBytecode (parser)) { |
|
685 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
686 } |
|
687 |
|
688 while ((*token = NW_WBXML_Parser_readUint8 (parser)) == |
|
689 NW_WBXML_SWITCH_PAGE) |
|
690 { |
|
691 if (NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
692 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
693 } |
|
694 if (!NW_WBXML_Parser_hasMoreBytecode (parser)) { |
|
695 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
696 } |
|
697 |
|
698 if (token_state == TOKEN_STATE_TAG){ |
|
699 parser->tag_code_page = NW_WBXML_Parser_readUint8 (parser); |
|
700 } else { |
|
701 parser->attribute_code_page = NW_WBXML_Parser_readUint8 (parser); |
|
702 } |
|
703 |
|
704 if((parser->cp_registry.count > 0) |
|
705 && ((parser->flags & NW_WBXML_REGISTRY_INIT) != NW_WBXML_REGISTRY_INIT)){ |
|
706 NW_ASSERT(parser->offset > 0); |
|
707 /* We have a registry but we haven't finished initing it yet */ |
|
708 // WLIU_DEBUG: RFileLogger::WriteFormat(_L("Browser"), _L("cp_count.txt"), EFileLoggingModeAppend, _L("=== cp_count: %x, pW->index: %x \n"), parser->cp_registry.realcount +1, parser->offset - parser->lastValid); |
|
709 NW_WBXML_CPRegistry_addEntry(&(parser->cp_registry), |
|
710 NW_WBXML_Parser_readUint8(parser), |
|
711 /* must use switch page token position */ |
|
712 parser->offset - 1, |
|
713 (NW_Uint8)token_state); |
|
714 } |
|
715 |
|
716 Handle_Codepage(parser); |
|
717 |
|
718 if (NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
719 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
720 } |
|
721 if (!NW_WBXML_Parser_hasMoreBytecode (parser)) { |
|
722 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
723 } |
|
724 } |
|
725 return NW_STAT_SUCCESS; |
|
726 } |
|
727 |
|
728 /* |
|
729 * Element parsing methods: The parser is made up of a set of methods |
|
730 * that know how to parse individual elements of the wbxml source. For |
|
731 * elements that repeat, these are implemented in iterators. Building |
|
732 * the parser from a set of element parsers and iterators makes it |
|
733 * simple to use the parser as a deserializer for wbxml elements. |
|
734 */ |
|
735 |
|
736 #define HAS_CONTENT(t) ((t)&NW_WBXML_FLAGS_CONTENT) |
|
737 #define HAS_ATTRIBUTES(t) ((t)&NW_WBXML_FLAGS_ATTRIBUTES) |
|
738 |
|
739 /* |
|
740 * Parse the token and name part of a tag. This generates a fully |
|
741 * qualified token. |
|
742 */ |
|
743 |
|
744 NW_Status_t |
|
745 NW_WBXML_Parser_tagNameParse(NW_WBXML_Parser_t *parser) |
|
746 { |
|
747 NW_Uint8 token; |
|
748 NW_Int32 ilen; |
|
749 NW_Uint32 index; |
|
750 NW_Uint32 fq_token; |
|
751 NW_Status_t status; |
|
752 |
|
753 NW_ASSERT(parser != NULL); |
|
754 |
|
755 Handle_Tag_Start(parser); |
|
756 |
|
757 CHECK_PARSER_STATUS; |
|
758 |
|
759 status = NW_WBXML_Parser_getNextToken (parser, &token, TOKEN_STATE_TAG); |
|
760 if(status != NW_STAT_SUCCESS){ |
|
761 return status; |
|
762 } |
|
763 |
|
764 fq_token = FqToken (parser, token, TOKEN_STATE_TAG); |
|
765 Handle_Fq_Token(parser, fq_token); |
|
766 |
|
767 if (HAS_CONTENT(fq_token) || HAS_ATTRIBUTES(fq_token) || |
|
768 (NW_WBXML_Parser_hasMoreBytecode (parser))) |
|
769 { |
|
770 if (NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
771 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
772 } |
|
773 } |
|
774 |
|
775 /* |
|
776 * Note that while the spec defines tokens for literal tags with |
|
777 * and without attributes and content, they are just |
|
778 * NW_WBXML_LITERAL with the content and/or attributes flags |
|
779 * set. So ... |
|
780 */ |
|
781 |
|
782 if ((token & NW_WBXML_MASK_TAG_ID) == NW_WBXML_LITERAL){ |
|
783 |
|
784 /* |
|
785 * TODO: Should check for another global token |
|
786 * and return an error? |
|
787 */ |
|
788 |
|
789 ilen = NW_WBXML_Parser_readMbUint32 (parser, &index); |
|
790 if(ilen < 0){ |
|
791 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
792 } |
|
793 |
|
794 Handle_Table_String(parser, index); |
|
795 |
|
796 if(NW_WBXML_Parser_advance(parser, ilen) < 0){ |
|
797 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
798 } |
|
799 } |
|
800 |
|
801 if (HAS_ATTRIBUTES (fq_token)){ /* Has attributes, possibly content */ |
|
802 status = NW_STAT_WBXML_HAS_ATTRIBUTES; |
|
803 if (HAS_CONTENT (fq_token)){ |
|
804 status = NW_STAT_WBXML_HAS_ATTR_CONTENT; |
|
805 } |
|
806 } |
|
807 |
|
808 else if (HAS_CONTENT (fq_token)){ /* Has content, no attributes */ |
|
809 status = NW_STAT_WBXML_HAS_CONTENT; |
|
810 } |
|
811 |
|
812 else{ /* No attributes, no content */ |
|
813 status = NW_STAT_SUCCESS; |
|
814 Handle_Tag_End(parser); |
|
815 } |
|
816 |
|
817 return status; |
|
818 } |
|
819 |
|
820 /* Parse an attribute list */ |
|
821 |
|
822 NW_Status_t |
|
823 NW_WBXML_Parser_attributeListIterate(NW_WBXML_Parser_t *parser) |
|
824 { |
|
825 NW_Uint8 token; |
|
826 NW_Status_t status; |
|
827 |
|
828 NW_ASSERT(parser != NULL); |
|
829 |
|
830 status = NW_WBXML_Parser_attributeParse (parser); |
|
831 if(status != NW_STAT_SUCCESS){ |
|
832 return status; |
|
833 } |
|
834 |
|
835 status = NW_WBXML_Parser_getNextToken (parser, &token, TOKEN_STATE_ATTR); |
|
836 if(status != NW_STAT_SUCCESS){ |
|
837 return status; |
|
838 } |
|
839 |
|
840 if (token == NW_WBXML_END){ |
|
841 return NW_STAT_WBXML_ITERATE_DONE; |
|
842 } |
|
843 return NW_STAT_WBXML_ITERATE_MORE; |
|
844 } |
|
845 |
|
846 static |
|
847 NW_Status_t |
|
848 NW_WBXML_Parser_attributeListParse(NW_WBXML_Parser_t *parser) |
|
849 { |
|
850 NW_Status_t status; |
|
851 |
|
852 /* Run the attribute list iterator till it completes */ |
|
853 |
|
854 while ((parser->flags & NW_WBXML_PARSER_S_MASK) == NW_WBXML_PARSER_OK){ |
|
855 status = NW_WBXML_Parser_attributeListIterate(parser); |
|
856 if(status == NW_STAT_WBXML_ITERATE_DONE){ |
|
857 return NW_STAT_SUCCESS; |
|
858 } |
|
859 if(status != NW_STAT_WBXML_ITERATE_MORE){ |
|
860 return status; |
|
861 } |
|
862 } |
|
863 return NW_WBXML_Parser_flagToStatus(parser); |
|
864 } |
|
865 |
|
866 /* |
|
867 * Parse a processing instruction |
|
868 */ |
|
869 static |
|
870 NW_Status_t |
|
871 NW_WBXML_Parser_piParse (NW_WBXML_Parser_t * parser, |
|
872 NW_Int32 token_state) |
|
873 { |
|
874 |
|
875 NW_Uint8 token; |
|
876 NW_Status_t status; |
|
877 |
|
878 status = NW_WBXML_Parser_getNextToken (parser, &token, token_state); |
|
879 if(status != NW_STAT_SUCCESS){ |
|
880 return status; |
|
881 } |
|
882 |
|
883 switch (token){ |
|
884 case NW_WBXML_PI: |
|
885 Handle_Pi(parser); |
|
886 /* |
|
887 * Advance past the PI token and then get the PI's |
|
888 * target and value |
|
889 */ |
|
890 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
891 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
892 } |
|
893 status = NW_WBXML_Parser_attributeParse (parser); |
|
894 if(status != NW_STAT_SUCCESS){ |
|
895 return status; |
|
896 } |
|
897 /* Advance past the PI's end token */ |
|
898 status = NW_WBXML_Parser_getNextToken (parser, &token, TOKEN_STATE_ATTR); |
|
899 if(status != NW_STAT_SUCCESS){ |
|
900 return status; |
|
901 } |
|
902 if (token == NW_WBXML_END){ |
|
903 Handle_Pi_End(parser); |
|
904 /* |
|
905 * Must advance the reader past the end token but since this |
|
906 * PI may be the last NW_Byte in the bytecode, first check to see |
|
907 * if there is any bytecode left. |
|
908 */ |
|
909 if (NW_WBXML_Parser_hasMoreBytecode (parser)){ |
|
910 NW_WBXML_Parser_advance (parser, 1); |
|
911 } |
|
912 } |
|
913 else |
|
914 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
915 break; |
|
916 default: |
|
917 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
918 } |
|
919 return NW_STAT_SUCCESS; |
|
920 } |
|
921 |
|
922 /* Parse an element, recursively parsing content */ |
|
923 |
|
924 static |
|
925 NW_Status_t |
|
926 NW_WBXML_Parser_elementParse (NW_WBXML_Parser_t * parser) |
|
927 { |
|
928 NW_Status_t tag_status = NW_STAT_SUCCESS; |
|
929 NW_Status_t status = NW_STAT_WBXML_ERROR_BYTECODE; |
|
930 |
|
931 if (++(parser->recursiveCallCnt) >= WBXML_MAX_RECURSIVE_CALL_DEPTH) { |
|
932 goto FuncExit; |
|
933 } |
|
934 |
|
935 /* The while loop checks parser status after each case. */ |
|
936 while ((parser->flags & NW_WBXML_PARSER_S_MASK) == NW_WBXML_PARSER_OK){ |
|
937 if (tag_status == NW_STAT_SUCCESS){ |
|
938 tag_status = NW_WBXML_Parser_tagNameParse(parser); |
|
939 if(tag_status == NW_STAT_SUCCESS){ |
|
940 status = NW_STAT_SUCCESS; /* Normal return */ |
|
941 goto FuncExit; |
|
942 } |
|
943 } |
|
944 |
|
945 else if((tag_status == NW_STAT_WBXML_HAS_ATTRIBUTES) || |
|
946 (tag_status == NW_STAT_WBXML_HAS_ATTR_CONTENT)) { |
|
947 |
|
948 status = NW_WBXML_Parser_attributeListParse (parser); |
|
949 if(status != NW_STAT_SUCCESS){ |
|
950 goto FuncExit; |
|
951 } |
|
952 |
|
953 if (NW_WBXML_Parser_hasMoreBytecode (parser)){ |
|
954 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
955 status = NW_STAT_WBXML_ERROR_BYTECODE; |
|
956 goto FuncExit; |
|
957 } |
|
958 } |
|
959 |
|
960 if(tag_status == NW_STAT_WBXML_HAS_ATTR_CONTENT) { |
|
961 tag_status = NW_STAT_WBXML_HAS_CONTENT; |
|
962 } |
|
963 else { |
|
964 Handle_Tag_End(parser); |
|
965 status = NW_STAT_SUCCESS; /* Normal return */ |
|
966 goto FuncExit; |
|
967 } |
|
968 |
|
969 /* TODO: else check for error (token >= 128) */ |
|
970 } |
|
971 |
|
972 else if((tag_status == NW_STAT_WBXML_HAS_CONTENT) || |
|
973 (tag_status == NW_STAT_WBXML_HAS_ATTR_CONTENT)) { |
|
974 |
|
975 status = NW_WBXML_Parser_contentParse(parser); |
|
976 if(status != NW_STAT_SUCCESS){ |
|
977 goto FuncExit; |
|
978 } |
|
979 |
|
980 Handle_Tag_End(parser); |
|
981 status = NW_STAT_SUCCESS; /* Normal return */ |
|
982 goto FuncExit; |
|
983 } |
|
984 else{ |
|
985 /* Unexpected NW_Byte code */ |
|
986 status = NW_STAT_WBXML_ERROR_BYTECODE; |
|
987 goto FuncExit; |
|
988 } |
|
989 } |
|
990 status = NW_STAT_WBXML_ERROR_BYTECODE; /* Bad parser status */ |
|
991 |
|
992 FuncExit: |
|
993 --(parser->recursiveCallCnt); |
|
994 return status; |
|
995 } |
|
996 |
|
997 |
|
998 /* Parse a sequence of text components until a non-text component is reached */ |
|
999 |
|
1000 |
|
1001 static |
|
1002 NW_Uint32 |
|
1003 isTextToken(NW_Uint8 token){ |
|
1004 if((token == NW_WBXML_STR_I) |
|
1005 ||(token == NW_WBXML_STR_T) |
|
1006 ||(token == NW_WBXML_OPAQUE) |
|
1007 ||(token == NW_WBXML_ENTITY) |
|
1008 ||(token == NW_WBXML_EXT_I_0) |
|
1009 || (token == NW_WBXML_EXT_I_1) |
|
1010 || (token == NW_WBXML_EXT_I_2) |
|
1011 || (token == NW_WBXML_EXT_T_0) |
|
1012 || (token == NW_WBXML_EXT_T_1) |
|
1013 || (token == NW_WBXML_EXT_T_2) |
|
1014 || (token == NW_WBXML_EXT_0) |
|
1015 || (token == NW_WBXML_EXT_1) |
|
1016 || (token == NW_WBXML_EXT_2)){ |
|
1017 return 1; |
|
1018 } |
|
1019 return 0; |
|
1020 } |
|
1021 |
|
1022 |
|
1023 NW_Status_t |
|
1024 NW_WBXML_Parser_textIterate(NW_WBXML_Parser_t * parser){ |
|
1025 |
|
1026 NW_Uint8 token; |
|
1027 NW_Int32 ilen = 0; |
|
1028 NW_Uint32 index; |
|
1029 NW_Uint32 e; |
|
1030 NW_Status_t status; |
|
1031 |
|
1032 status = NW_WBXML_Parser_getNextToken (parser, &token, TOKEN_STATE_TAG); |
|
1033 if(status != NW_STAT_SUCCESS){ |
|
1034 return status; |
|
1035 } |
|
1036 |
|
1037 switch (token){ |
|
1038 case NW_WBXML_STR_I: |
|
1039 Handle_Content(parser); |
|
1040 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1041 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1042 } |
|
1043 ilen = NW_WBXML_Parser_getInlineStrLen(parser, parser->doc); |
|
1044 if(ilen < 0){ |
|
1045 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1046 } |
|
1047 Handle_Inline_String(parser, (NW_Uint32)ilen); |
|
1048 if(NW_WBXML_Parser_advance(parser, ilen) < 0){ |
|
1049 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1050 } |
|
1051 break; |
|
1052 case NW_WBXML_STR_T: |
|
1053 Handle_Content(parser); |
|
1054 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1055 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1056 } |
|
1057 ilen = NW_WBXML_Parser_readMbUint32 (parser, &index); |
|
1058 if ((ilen < 0) || (index >= parser->doc->strtbl.length)) { |
|
1059 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1060 } |
|
1061 if (!NW_String_valid(parser->doc->strtbl.data + index, |
|
1062 parser->doc->strtbl.length - index, |
|
1063 parser->doc->charset)) { |
|
1064 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1065 } |
|
1066 Handle_Table_String(parser, index); |
|
1067 if(NW_WBXML_Parser_advance(parser, ilen)< 0){ |
|
1068 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1069 } |
|
1070 break; |
|
1071 case NW_WBXML_ENTITY: |
|
1072 Handle_Content(parser); |
|
1073 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1074 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1075 } |
|
1076 ilen = NW_WBXML_Parser_readMbUint32 (parser, &e); |
|
1077 if(ilen < 0){ |
|
1078 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1079 } |
|
1080 if(NW_WBXML_Parser_advance (parser, ilen) < 0){ |
|
1081 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1082 } |
|
1083 Handle_Entity(parser, e); |
|
1084 break; |
|
1085 case NW_WBXML_EXT_I_0: |
|
1086 case NW_WBXML_EXT_I_1: |
|
1087 case NW_WBXML_EXT_I_2: |
|
1088 case NW_WBXML_EXT_T_0: |
|
1089 case NW_WBXML_EXT_T_1: |
|
1090 case NW_WBXML_EXT_T_2: |
|
1091 case NW_WBXML_EXT_0: |
|
1092 case NW_WBXML_EXT_1: |
|
1093 case NW_WBXML_EXT_2: |
|
1094 Handle_Content(parser); |
|
1095 status = NW_WBXML_Parser_extensionParse (parser, TOKEN_STATE_TAG); |
|
1096 if(status != NW_STAT_SUCCESS){ |
|
1097 return status; |
|
1098 } |
|
1099 break; |
|
1100 case NW_WBXML_OPAQUE: |
|
1101 Handle_Content(parser); |
|
1102 status = NW_WBXML_Parser_opaqueParse (parser, TOKEN_STATE_TAG); |
|
1103 if(status != NW_STAT_SUCCESS){ |
|
1104 return status; |
|
1105 } |
|
1106 break; |
|
1107 case NW_WBXML_PI: |
|
1108 status = NW_WBXML_Parser_piParse (parser, TOKEN_STATE_TAG); |
|
1109 if (status != NW_STAT_SUCCESS){ |
|
1110 return status; |
|
1111 } |
|
1112 break; |
|
1113 default: |
|
1114 return NW_STAT_FAILURE; |
|
1115 } |
|
1116 if (NW_WBXML_Parser_hasMoreBytecode (parser)) { |
|
1117 status = NW_WBXML_Parser_getNextToken(parser, &token, TOKEN_STATE_TAG); |
|
1118 if(status != NW_STAT_SUCCESS){ |
|
1119 return status; |
|
1120 } |
|
1121 if(isTextToken(token)) |
|
1122 return NW_STAT_WBXML_ITERATE_MORE; |
|
1123 } |
|
1124 return NW_STAT_WBXML_ITERATE_DONE; |
|
1125 } |
|
1126 |
|
1127 static |
|
1128 NW_Status_t |
|
1129 NW_WBXML_Parser_textParse(NW_WBXML_Parser_t * parser){ |
|
1130 |
|
1131 NW_Status_t status; |
|
1132 |
|
1133 /* Run the text iterator till it completes */ |
|
1134 |
|
1135 while ((parser->flags & NW_WBXML_PARSER_S_MASK) == NW_WBXML_PARSER_OK){ |
|
1136 status = NW_WBXML_Parser_textIterate(parser); |
|
1137 if(status == NW_STAT_WBXML_ITERATE_DONE){ |
|
1138 return NW_STAT_SUCCESS; |
|
1139 } |
|
1140 if(status != NW_STAT_WBXML_ITERATE_MORE){ |
|
1141 return status; |
|
1142 } |
|
1143 } |
|
1144 return NW_WBXML_Parser_flagToStatus(parser); |
|
1145 } |
|
1146 |
|
1147 |
|
1148 /* Parse tag content */ |
|
1149 |
|
1150 NW_Status_t |
|
1151 NW_WBXML_Parser_contentParse (NW_WBXML_Parser_t * parser){ |
|
1152 |
|
1153 NW_Uint8 token; |
|
1154 NW_Status_t status; |
|
1155 |
|
1156 while ((parser->flags & NW_WBXML_PARSER_S_MASK) == NW_WBXML_PARSER_OK){ |
|
1157 |
|
1158 status = NW_WBXML_Parser_getNextToken (parser, &token, TOKEN_STATE_TAG); |
|
1159 if(status != NW_STAT_SUCCESS){ |
|
1160 return status; |
|
1161 } |
|
1162 |
|
1163 switch (token){ |
|
1164 case NW_WBXML_END: |
|
1165 if (NW_WBXML_Parser_hasMoreBytecode (parser)){ |
|
1166 NW_WBXML_Parser_advance (parser, 1); |
|
1167 } |
|
1168 return NW_STAT_SUCCESS; /* Normal return */ |
|
1169 |
|
1170 case NW_WBXML_STR_I: |
|
1171 case NW_WBXML_STR_T: |
|
1172 case NW_WBXML_ENTITY: |
|
1173 case NW_WBXML_PI: |
|
1174 case NW_WBXML_EXT_I_0: |
|
1175 case NW_WBXML_EXT_I_1: |
|
1176 case NW_WBXML_EXT_I_2: |
|
1177 case NW_WBXML_EXT_T_0: |
|
1178 case NW_WBXML_EXT_T_1: |
|
1179 case NW_WBXML_EXT_T_2: |
|
1180 case NW_WBXML_EXT_0: |
|
1181 case NW_WBXML_EXT_1: |
|
1182 case NW_WBXML_EXT_2: |
|
1183 case NW_WBXML_OPAQUE: |
|
1184 status = NW_WBXML_Parser_textParse(parser); |
|
1185 if(status != NW_STAT_SUCCESS){ |
|
1186 return status; |
|
1187 } |
|
1188 break; |
|
1189 case NW_WBXML_LITERAL: |
|
1190 case NW_WBXML_LITERAL_A: |
|
1191 case NW_WBXML_LITERAL_C: |
|
1192 case NW_WBXML_LITERAL_AC: |
|
1193 default: |
|
1194 Handle_Content(parser); |
|
1195 status = NW_WBXML_Parser_elementParse (parser); |
|
1196 if(status != NW_STAT_SUCCESS){ |
|
1197 return status; |
|
1198 } |
|
1199 break; |
|
1200 } |
|
1201 } |
|
1202 return NW_WBXML_Parser_flagToStatus(parser); |
|
1203 } |
|
1204 |
|
1205 /* Parse an extension */ |
|
1206 |
|
1207 NW_Status_t |
|
1208 NW_WBXML_Parser_extensionParse (NW_WBXML_Parser_t * parser, |
|
1209 NW_Int32 token_state) |
|
1210 { |
|
1211 NW_Uint8 token = 0; |
|
1212 NW_Uint32 fq_token; |
|
1213 int ilen; |
|
1214 NW_Uint32 value; |
|
1215 NW_Status_t status; |
|
1216 |
|
1217 /* if (token_state == TOKEN_STATE_TAG) |
|
1218 * handler = parser->handler; TODO: deal with this |
|
1219 */ |
|
1220 |
|
1221 Handle_Extension(parser); |
|
1222 |
|
1223 status = NW_WBXML_Parser_getNextToken (parser, &token, token_state); |
|
1224 if(status != NW_STAT_SUCCESS){ |
|
1225 return status; |
|
1226 } |
|
1227 |
|
1228 fq_token = FqToken (parser, token, token_state); |
|
1229 Handle_Fq_Token(parser, fq_token); |
|
1230 |
|
1231 switch (token){ |
|
1232 case NW_WBXML_EXT_I_0: |
|
1233 case NW_WBXML_EXT_I_1: |
|
1234 case NW_WBXML_EXT_I_2: |
|
1235 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1236 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1237 } |
|
1238 |
|
1239 ilen = NW_WBXML_Parser_getInlineStrLen(parser, parser->doc); |
|
1240 if(ilen < 0){ |
|
1241 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1242 } |
|
1243 |
|
1244 Handle_Inline_String(parser, (NW_Uint32)ilen); |
|
1245 |
|
1246 if(NW_WBXML_Parser_advance(parser, ilen)<0){ |
|
1247 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1248 } |
|
1249 break; |
|
1250 case NW_WBXML_EXT_T_0: |
|
1251 case NW_WBXML_EXT_T_1: |
|
1252 case NW_WBXML_EXT_T_2: |
|
1253 |
|
1254 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1255 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1256 } |
|
1257 |
|
1258 ilen = NW_WBXML_Parser_readMbUint32 (parser, &value); |
|
1259 |
|
1260 if(ilen < 0){ |
|
1261 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1262 } |
|
1263 |
|
1264 if (parser->ext_t_not_table_index == 0) { |
|
1265 Handle_Table_String(parser, value); |
|
1266 } else { |
|
1267 Handle_Binary(parser, value); /* handle ext_t anonymous int */ |
|
1268 } |
|
1269 if(NW_WBXML_Parser_advance (parser, ilen) < 0){ |
|
1270 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1271 } |
|
1272 break; |
|
1273 case NW_WBXML_EXT_0: |
|
1274 case NW_WBXML_EXT_1: |
|
1275 case NW_WBXML_EXT_2: |
|
1276 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1277 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1278 } |
|
1279 /* Note - For an extension token without other parameters the |
|
1280 second parameter to Handle_Binary is bogus. The callback is here |
|
1281 so that the parser client can manage its internal state. */ |
|
1282 Handle_Binary(parser, 0); |
|
1283 break; |
|
1284 default: |
|
1285 NW_ASSERT(NW_FALSE); |
|
1286 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1287 } |
|
1288 return NW_STAT_SUCCESS; |
|
1289 } |
|
1290 |
|
1291 |
|
1292 /* |
|
1293 * Parse an attribute |
|
1294 */ |
|
1295 |
|
1296 |
|
1297 |
|
1298 NW_Status_t |
|
1299 NW_WBXML_Parser_attributeNameParse (NW_WBXML_Parser_t * parser){ |
|
1300 |
|
1301 NW_Uint8 token; |
|
1302 NW_Uint32 fq_token; |
|
1303 NW_Uint32 index; |
|
1304 NW_Int32 ilen; |
|
1305 NW_Status_t status; |
|
1306 |
|
1307 if (!NW_WBXML_Parser_hasMoreBytecode(parser)) { |
|
1308 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1309 } |
|
1310 |
|
1311 status = NW_WBXML_Parser_getNextToken (parser, &token, TOKEN_STATE_ATTR); |
|
1312 if(status != NW_STAT_SUCCESS){ |
|
1313 return status; |
|
1314 } |
|
1315 |
|
1316 if (token < 128){ |
|
1317 Handle_Attr_Start(parser); |
|
1318 if (parser->status == NW_STAT_OUT_OF_MEMORY) { |
|
1319 return parser->status; |
|
1320 } |
|
1321 if(NW_WBXML_Parser_advance (parser, 1)<0){ |
|
1322 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1323 } |
|
1324 |
|
1325 fq_token = FqToken (parser, token, TOKEN_STATE_ATTR); |
|
1326 |
|
1327 Handle_Fq_Token(parser, fq_token); |
|
1328 } |
|
1329 |
|
1330 else{ |
|
1331 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1332 } |
|
1333 |
|
1334 if (token == NW_WBXML_LITERAL){ |
|
1335 /* TODO: Should check for another global token and return an error? */ |
|
1336 ilen = NW_WBXML_Parser_readMbUint32 (parser, &index); |
|
1337 if(ilen < 0){ |
|
1338 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1339 } |
|
1340 Handle_Table_String(parser, index); |
|
1341 if(NW_WBXML_Parser_advance(parser, ilen) < 0){ |
|
1342 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1343 } |
|
1344 } |
|
1345 return NW_STAT_SUCCESS; |
|
1346 } |
|
1347 |
|
1348 |
|
1349 NW_Status_t |
|
1350 NW_WBXML_Parser_attributeValsIterate (NW_WBXML_Parser_t * parser) |
|
1351 { |
|
1352 NW_Uint8 token; |
|
1353 NW_Uint32 fq_token; |
|
1354 NW_Uint32 index; |
|
1355 NW_Uint32 e; |
|
1356 NW_Int32 ilen; |
|
1357 NW_Status_t status; |
|
1358 |
|
1359 status = NW_WBXML_Parser_getNextToken (parser, &token, TOKEN_STATE_ATTR); |
|
1360 if(status != NW_STAT_SUCCESS){ |
|
1361 return status; |
|
1362 } |
|
1363 |
|
1364 if (token == NW_WBXML_STR_I){ |
|
1365 /* NW_WBXML_ATTR_COMPONENT_STRING; */ |
|
1366 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1367 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1368 } |
|
1369 ilen = NW_WBXML_Parser_getInlineStrLen(parser, parser->doc); |
|
1370 if(ilen < 0){ |
|
1371 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1372 } |
|
1373 Handle_Attr_Val(parser); |
|
1374 Handle_Inline_String(parser, (NW_Uint32) ilen); |
|
1375 if(NW_WBXML_Parser_advance(parser, ilen) < 0){ |
|
1376 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1377 } |
|
1378 } |
|
1379 else if (token == NW_WBXML_STR_T){ |
|
1380 /* NW_WBXML_ATTR_COMPONENT_STRING; */ |
|
1381 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1382 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1383 } |
|
1384 ilen = NW_WBXML_Parser_readMbUint32 (parser, &index); |
|
1385 if(ilen < 0){ |
|
1386 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1387 } |
|
1388 Handle_Attr_Val(parser); |
|
1389 Handle_Table_String(parser, index); |
|
1390 if(NW_WBXML_Parser_advance(parser, ilen)<0){ |
|
1391 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1392 } |
|
1393 } |
|
1394 else if (token == NW_WBXML_OPAQUE){ |
|
1395 /* NW_WBXML_ATTR_COMPONENT_OPAQUE; */ |
|
1396 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1397 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1398 } |
|
1399 ilen = NW_WBXML_Parser_readMbUint32 (parser, &index); |
|
1400 if(ilen < 0){ |
|
1401 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1402 } |
|
1403 /* Move past the length NW_Byte(s) */ |
|
1404 if(NW_WBXML_Parser_advance (parser, ilen) < 0){ |
|
1405 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1406 } |
|
1407 Handle_Attr_Val(parser); |
|
1408 Handle_Opaque(parser, index); |
|
1409 if(NW_WBXML_Parser_advance (parser, (NW_Int32)index) < 0){ |
|
1410 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1411 } |
|
1412 } |
|
1413 else if (token == NW_WBXML_ENTITY){ |
|
1414 /*NW_WBXML_ATTR_COMPONENT_ENTITY; */ |
|
1415 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1416 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1417 } |
|
1418 ilen = NW_WBXML_Parser_readMbUint32 (parser,&e); |
|
1419 if(ilen < 0){ |
|
1420 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1421 } |
|
1422 Handle_Entity(parser, e); |
|
1423 if(NW_WBXML_Parser_advance (parser, ilen) < 0){ |
|
1424 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1425 } |
|
1426 } |
|
1427 else if ((token == NW_WBXML_EXT_I_0) |
|
1428 || (token == NW_WBXML_EXT_I_1) |
|
1429 || (token == NW_WBXML_EXT_I_2) |
|
1430 || (token == NW_WBXML_EXT_T_0) |
|
1431 || (token == NW_WBXML_EXT_T_1) |
|
1432 || (token == NW_WBXML_EXT_T_2) |
|
1433 || (token == NW_WBXML_EXT_0) |
|
1434 || (token == NW_WBXML_EXT_1) |
|
1435 || (token == NW_WBXML_EXT_2)){ |
|
1436 |
|
1437 /* NW_WBXML_ATTR_COMPONENT_EXT; */ |
|
1438 Handle_Attr_Val(parser); |
|
1439 status = NW_WBXML_Parser_extensionParse (parser, TOKEN_STATE_ATTR); |
|
1440 if(status != NW_STAT_SUCCESS){ |
|
1441 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1442 } |
|
1443 } |
|
1444 else if (token >= 128){ |
|
1445 /*NW_WBXML_ATTR_COMPONENT_TOKEN; */ |
|
1446 fq_token = FqToken(parser, token, TOKEN_STATE_ATTR); |
|
1447 Handle_Attr_Val(parser); |
|
1448 Handle_Fq_Token(parser, fq_token); |
|
1449 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1450 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1451 } |
|
1452 } |
|
1453 |
|
1454 status = NW_WBXML_Parser_getNextToken (parser, &token, TOKEN_STATE_ATTR); |
|
1455 if(status != NW_STAT_SUCCESS){ |
|
1456 return status; |
|
1457 } |
|
1458 |
|
1459 /* |
|
1460 * Attribute tokens are either text tokens or |
|
1461 * dictionary-defined tokens > 128 |
|
1462 */ |
|
1463 if(isTextToken(token) || (token >=128)){ |
|
1464 |
|
1465 return NW_STAT_WBXML_ITERATE_MORE; /* Normal exit */ |
|
1466 } |
|
1467 else /*if ((token < 128) || (token == NW_WBXML_END) |
|
1468 || (token == NW_WBXML_LITERAL))*/{ |
|
1469 /*parser->state &= ~NW_WBXML_PARSER_S_ATTR_VAL; */ |
|
1470 /* Don't advance parser */ |
|
1471 return NW_STAT_WBXML_ITERATE_DONE; /* Normal exit */ |
|
1472 } |
|
1473 } |
|
1474 |
|
1475 NW_Status_t |
|
1476 NW_WBXML_Parser_attributeParse(NW_WBXML_Parser_t *parser) |
|
1477 { |
|
1478 NW_Status_t status; |
|
1479 |
|
1480 status = NW_WBXML_Parser_attributeNameParse(parser); |
|
1481 if(status != NW_STAT_SUCCESS){ |
|
1482 return status; |
|
1483 } |
|
1484 while ((parser->flags & NW_WBXML_PARSER_S_MASK) == NW_WBXML_PARSER_OK){ |
|
1485 status = NW_WBXML_Parser_attributeValsIterate(parser); |
|
1486 if(status == NW_STAT_WBXML_ITERATE_DONE){ |
|
1487 return NW_STAT_SUCCESS; |
|
1488 } |
|
1489 if(status != NW_STAT_WBXML_ITERATE_MORE){ |
|
1490 return status; |
|
1491 } |
|
1492 } |
|
1493 return NW_WBXML_Parser_flagToStatus(parser); |
|
1494 } |
|
1495 |
|
1496 |
|
1497 /* |
|
1498 * Parse opaque data |
|
1499 */ |
|
1500 |
|
1501 NW_Status_t |
|
1502 NW_WBXML_Parser_opaqueParse (NW_WBXML_Parser_t * parser, |
|
1503 NW_Int32 token_state) |
|
1504 { |
|
1505 |
|
1506 NW_Uint32 index; |
|
1507 NW_Int32 ilen = 0; |
|
1508 NW_Uint8 token; |
|
1509 NW_Status_t status; |
|
1510 |
|
1511 status = NW_WBXML_Parser_getNextToken (parser, &token, token_state); |
|
1512 if(status != NW_STAT_SUCCESS){ |
|
1513 return status; |
|
1514 } |
|
1515 |
|
1516 switch (token){ |
|
1517 case NW_WBXML_OPAQUE: |
|
1518 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1519 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1520 } |
|
1521 ilen = NW_WBXML_Parser_readMbUint32 (parser, &index); |
|
1522 if(ilen < 0){ |
|
1523 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1524 } |
|
1525 if(NW_WBXML_Parser_advance (parser, ilen) < 0){ |
|
1526 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1527 } |
|
1528 Handle_Opaque(parser,index); |
|
1529 if(NW_WBXML_Parser_advance (parser, (NW_Int32)index) < 0){ |
|
1530 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1531 } |
|
1532 break; |
|
1533 default: |
|
1534 /* return NW_STAT_WBXML_ERROR_BYTECODE;*/ |
|
1535 NW_ASSERT(NW_FALSE); /* Never reached */ |
|
1536 } |
|
1537 return NW_STAT_SUCCESS; |
|
1538 } |
|
1539 |
|
1540 |
|
1541 /* |
|
1542 * Parse the body of a document |
|
1543 * |
|
1544 * RETURN NW_STAT_SUCCESS |
|
1545 * NW_STAT_OUT_OF_MEMORY |
|
1546 * NW_STAT_BAD_INPUT_PARAM |
|
1547 * NW_STAT_WBXML_ERROR_BYTECODE |
|
1548 * NW_STAT_WBXML_ERROR_CHARSET_UNSUPPORTED |
|
1549 */ |
|
1550 |
|
1551 NW_Status_t |
|
1552 NW_WBXML_Parser_bodyParse (NW_WBXML_Parser_t * parser) |
|
1553 { |
|
1554 NW_Status_t status; |
|
1555 NW_Uint8 token; |
|
1556 |
|
1557 NW_ASSERT(parser != NULL); |
|
1558 // WLIU_DEBUG: RFileLogger::WriteFormat(_L("Browser"), _L("cp_count.txt"), EFileLoggingModeAppend, _L("====== body parse starts =====\n")); |
|
1559 |
|
1560 /* This is not quite the WBXML grammar because we want to permit |
|
1561 loose HTML docs where there is no one document node. */ |
|
1562 while (((parser->flags & NW_WBXML_PARSER_S_MASK) == NW_WBXML_PARSER_OK) |
|
1563 && NW_WBXML_Parser_hasMoreBytecode (parser)) { |
|
1564 |
|
1565 status = NW_WBXML_Parser_getNextToken (parser, &token, TOKEN_STATE_TAG); |
|
1566 if(status != NW_STAT_SUCCESS){ |
|
1567 return status; |
|
1568 } |
|
1569 |
|
1570 switch (token){ |
|
1571 case NW_WBXML_END: |
|
1572 if (NW_WBXML_Parser_hasMoreBytecode (parser)) { |
|
1573 if(NW_WBXML_Parser_advance (parser, 1) < 0){ |
|
1574 return NW_STAT_WBXML_ERROR_BYTECODE; |
|
1575 } |
|
1576 Handle_Tag_End(parser); |
|
1577 } |
|
1578 break; |
|
1579 |
|
1580 case NW_WBXML_STR_I: |
|
1581 case NW_WBXML_STR_T: |
|
1582 case NW_WBXML_ENTITY: |
|
1583 case NW_WBXML_PI: |
|
1584 case NW_WBXML_EXT_I_0: |
|
1585 case NW_WBXML_EXT_I_1: |
|
1586 case NW_WBXML_EXT_I_2: |
|
1587 case NW_WBXML_EXT_T_0: |
|
1588 case NW_WBXML_EXT_T_1: |
|
1589 case NW_WBXML_EXT_T_2: |
|
1590 case NW_WBXML_EXT_0: |
|
1591 case NW_WBXML_EXT_1: |
|
1592 case NW_WBXML_EXT_2: |
|
1593 case NW_WBXML_OPAQUE: |
|
1594 status = NW_WBXML_Parser_textParse(parser); |
|
1595 if(status != NW_STAT_SUCCESS){ |
|
1596 return status; |
|
1597 } |
|
1598 break; |
|
1599 |
|
1600 case NW_WBXML_LITERAL: |
|
1601 case NW_WBXML_LITERAL_A: |
|
1602 case NW_WBXML_LITERAL_C: |
|
1603 case NW_WBXML_LITERAL_AC: |
|
1604 default: |
|
1605 status = NW_WBXML_Parser_elementParse (parser); |
|
1606 if(status != NW_STAT_SUCCESS){ |
|
1607 return status; |
|
1608 } |
|
1609 break; |
|
1610 } |
|
1611 } |
|
1612 CHECK_PARSER_STATUS; |
|
1613 |
|
1614 /* |
|
1615 * If we have a registry then it must be inited at this point, so |
|
1616 * set the init flag. |
|
1617 */ |
|
1618 |
|
1619 if((parser->cp_registry.count > 0) |
|
1620 && ((parser->flags & NW_WBXML_REGISTRY_INIT) != NW_WBXML_REGISTRY_INIT)){ |
|
1621 parser->flags |= NW_WBXML_REGISTRY_INIT; |
|
1622 } |
|
1623 |
|
1624 // WLIU_DEBUG: RFileLogger::WriteFormat(_L("Browser"), _L("cp_count.txt"), EFileLoggingModeAppend, _L("====== body parse ends =====\n")); |
|
1625 |
|
1626 if (parser->handler && parser->handler->EndDocument_CB){ |
|
1627 return (*(parser->handler->EndDocument_CB)) (parser, parser->context); |
|
1628 } |
|
1629 return NW_STAT_SUCCESS; |
|
1630 } |
|
1631 |
|
1632 |
|
1633 /* |
|
1634 * Cache the parser's event handler and context |
|
1635 * |
|
1636 * RETURN: NW_STAT_SUCCESS |
|
1637 */ |
|
1638 |
|
1639 EXPORT_C NW_Status_t |
|
1640 NW_WBXML_Parser_registerHandler (NW_WBXML_Parser_t * parser, |
|
1641 const struct NW_WBXML_EventHandler_s * handler, |
|
1642 void *context) |
|
1643 { |
|
1644 |
|
1645 NW_ASSERT(parser != NULL); |
|
1646 |
|
1647 parser->handler = handler; |
|
1648 parser->context = context; |
|
1649 |
|
1650 return NW_STAT_SUCCESS; |
|
1651 } |