File: | libsynthesis/src/syncml_tk/src/sml/xlt/all/xltdecwbxml.c |
Warning: | line 1019, column 5 Value stored to '_err' is never read |
1 | /** |
2 | * @file |
3 | * WBXML decoder |
4 | * |
5 | * @target_system all |
6 | * @target_os all |
7 | * @description The WBXML scanner/tokenizer. Used by the SyncML parser. |
8 | */ |
9 | |
10 | |
11 | /* |
12 | * Copyright Notice |
13 | * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication |
14 | * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., |
15 | * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). |
16 | * All Rights Reserved. |
17 | * Implementation of all or part of any Specification may require |
18 | * licenses under third party intellectual property rights, |
19 | * including without limitation, patent rights (such a third party |
20 | * may or may not be a Supporter). The Sponsors of the Specification |
21 | * are not responsible and shall not be held responsible in any |
22 | * manner for identifying or failing to identify any or all such |
23 | * third party intellectual property rights. |
24 | * |
25 | * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED |
26 | * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, |
27 | * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, |
28 | * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML |
29 | * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING |
30 | * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION |
31 | * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF |
32 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT |
33 | * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., |
34 | * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY |
35 | * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF |
36 | * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF |
37 | * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, |
38 | * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH |
39 | * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED |
40 | * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. |
41 | * |
42 | * The above notice and this paragraph must be included on all copies |
43 | * of this document that are made. |
44 | * |
45 | */ |
46 | |
47 | #include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++ |
48 | |
49 | #include "define.h" |
50 | #ifdef __SML_WBXML__ |
51 | /*************************************************************************/ |
52 | /* Definitions */ |
53 | /*************************************************************************/ |
54 | #include "xltdevinf.h" |
55 | #include "xltdeccom.h" |
56 | #include "xlttags.h" |
57 | #include "xltutilstack.h" |
58 | #include "xltdec.h" |
59 | |
60 | #include "smldtd.h" |
61 | #include "smldevinfdtd.h" |
62 | #include "smlmetinfdtd.h" |
63 | #include "mgrutil.h" |
64 | |
65 | #include <libmem.h> |
66 | #include <libstr.h> |
67 | |
68 | #include <smlerr.h> |
69 | |
70 | #ifdef IS_END /* to avoid redefinition of this macro */ |
71 | #undef IS_END |
72 | #endif |
73 | |
74 | void |
75 | subdtdDecodeWbxml(XltDecoderPtr_t pDecoder,SmlPcdataPtr_t *ppPcdata); |
76 | |
77 | |
78 | /* WBXML version that this parser knows */ |
79 | #define _MAJOR_VERSION1 1 |
80 | #define _MINOR_VERSION2 2 |
81 | #define _MAX_PARSER_MINOR_VERSION3 3 // luz: WBXML 1.3 seems to work identically in the SyncML context |
82 | |
83 | #define TAG_STATE0 0 |
84 | #define ATTRIBUTE_STATE1 1 |
85 | |
86 | /* various checks about wbxml token */ |
87 | #define HAS_ATTRIBUTES(tag)(*tag & 0x80) (*tag & 0x80) |
88 | #define HAS_CONTENT(tag)(*tag & 0x40) (*tag & 0x40) |
89 | #define IDENTITY(tag)(*tag & 0x3F) (*tag & 0x3F) |
90 | |
91 | #define IS_SWITCH(tok)(*(tok) == 0x00) (*(tok) == 0x00) |
92 | #define IS_END(tok)(*(tok) == 0x01) (*(tok) == 0x01) |
93 | #define IS_ENTITY(tok)(*(tok) == 0x02) (*(tok) == 0x02) |
94 | #define IS_STR_I(tok)(*(tok) == 0x03) (*(tok) == 0x03) |
95 | #define IS_LITERAL(tok)((*tok & 0x3F) == 0x04) (IDENTITY(tok)(*tok & 0x3F) == 0x04) |
96 | // Note: gcc cannot parse multi-line macros when file has DOS line ends |
97 | #define IS_EXT_I(tok)((*(tok) == 0x40) || (*(tok) == 0x41) || (*(tok) == 0x42)) ((*(tok) == 0x40) || (*(tok) == 0x41) || (*(tok) == 0x42)) |
98 | #define IS_PI(tok)(*(tok) == 0x43) (*(tok) == 0x43) |
99 | #define IS_EXT_T(tok)((*(tok) == 0x80) || (*(tok) == 0x81) || (*(tok) == 0x82)) ((*(tok) == 0x80) || (*(tok) == 0x81) || (*(tok) == 0x82)) |
100 | #define IS_STR_T(tok)(*(tok) == 0x83) (*(tok) == 0x83) |
101 | #define IS_EXT(tok)((*(tok) == 0xC0) || (*(tok) == 0xC1) || (*(tok) == 0xC2)) ((*(tok) == 0xC0) || (*(tok) == 0xC1) || (*(tok) == 0xC2)) |
102 | #define IS_OPAQUE(tok)(*(tok) == 0xC3) (*(tok) == 0xC3) |
103 | #define IS_STRING(tok)((*(tok) == 0x03) || (*(tok) == 0x83)) (IS_STR_I(tok)(*(tok) == 0x03) || IS_STR_T(tok)(*(tok) == 0x83)) |
104 | #define IS_EXTENSION(tok)(((*(tok) == 0x40) || (*(tok) == 0x41) || (*(tok) == 0x42)) || ((*(tok) == 0x80) || (*(tok) == 0x81) || (*(tok) == 0x82)) || ((*(tok) == 0xC0) || (*(tok) == 0xC1) || (*(tok) == 0xC2))) (IS_EXT_I(tok)((*(tok) == 0x40) || (*(tok) == 0x41) || (*(tok) == 0x42)) || IS_EXT_T(tok)((*(tok) == 0x80) || (*(tok) == 0x81) || (*(tok) == 0x82)) || IS_EXT(tok)((*(tok) == 0xC0) || (*(tok) == 0xC1) || (*(tok) == 0xC2))) |
105 | |
106 | #define IS_ATTRIBUTE_VALUE(tok)(*(tok) & 0x80) (*(tok) & 0x80) |
107 | #define IS_ATTRIBUTE_START(tok)(~(*(tok) & 0x80)) (~IS_ATTRIBUTE_VALUE(tok)(*(tok) & 0x80)) |
108 | |
109 | |
110 | /** @copydoc wbxmlScannerPriv_s */ |
111 | typedef struct wbxmlScannerPriv_s wbxmlScannerPriv_t, *wbxmlScannerPrivPtr_t; |
112 | /** |
113 | * Private Interface for the WBXML scanner. |
114 | * |
115 | * The private scanner interface contains some additional member attributes |
116 | * that are not listed in the public interface, e.g. a copy of the string |
117 | * table and some other items that do not need to be known outside the |
118 | * scanner module. |
119 | */ |
120 | struct wbxmlScannerPriv_s |
121 | { |
122 | /* public methods */ |
123 | Ret_t (*nextTok)(XltDecScannerPtr_t); |
124 | Ret_t (*destroy)(XltDecScannerPtr_t); |
125 | Ret_t (*pushTok)(XltDecScannerPtr_t); |
126 | void (*setBuf)(XltDecScannerPtr_t pScanner, const MemPtr_t pBufStart, const MemPtr_t pBufEnd); |
127 | MemPtr_t (*getPos)(XltDecScannerPtr_t pScanner, Long_t *remaining); |
128 | |
129 | /* public attributes */ |
130 | XltDecTokenPtr_t curtok; /**< current token */ |
131 | Long_t charset; /**< character set as specified in the |
132 | WBXML header */ |
133 | String_t charsetStr; /**< NULL */ |
134 | Long_t pubID; /**< document public identifier as |
135 | specified in the WBXML header */ |
136 | String_t pubIDStr; /**< pubID as a string - valid only when |
137 | pubID == 0 */ |
138 | Flag_t finished; /**< set when end of buffer is reached */ |
139 | |
140 | /* private attributes */ |
141 | MemPtr_t pos; /**< current buffer position */ |
142 | MemPtr_t bufend; /**< end of buffer */ |
143 | Long_t pubIDIdx; /**< strtbl index of the string |
144 | version of the pubID - valid only |
145 | when pubID == 0 */ |
146 | |
147 | XltUtilStackPtr_t tagstack; /**< stack of open start tags */ |
148 | |
149 | MemPtr_t strtbl; /**< copy of the string table */ |
150 | Long_t strtbllen; /**< length of the string table */ |
151 | |
152 | Byte_t state; /**< tag state or attribute state */ |
153 | SmlPcdataExtension_t cptag; /**< current codepage for tags */ |
154 | Byte_t cpattr; /**< current codepage for attributes */ |
155 | SmlPcdataExtension_t activeExt; /**< the active Sub DTD */ |
156 | }; |
157 | |
158 | /* typedef for multi-byte unsigned integers as specified in the |
159 | WAP Binary XML Content Format specification */ |
160 | typedef Long_t MBINT; |
161 | |
162 | /* |
163 | * Public methods of the scanner interface. |
164 | * |
165 | * Description see XLTDecCom.h. |
166 | */ |
167 | static Ret_t _destroy(XltDecScannerPtr_t); |
168 | static Ret_t _nextTok(XltDecScannerPtr_t); |
169 | static Ret_t _pushTok(XltDecScannerPtr_t); |
170 | static void _setBuf(XltDecScannerPtr_t, const MemPtr_t, const MemPtr_t); |
171 | static MemPtr_t _getPos(XltDecScannerPtr_t, Long_t *remaining); |
172 | |
173 | /** |
174 | * Advance the current position pointer after checking whether the end of |
175 | * the buffer has been reached. If the end of the buffer has been reached |
176 | * the scanner's finished flag is set. |
177 | * |
178 | * @return 0, if end of buffer has been reached |
179 | * 1 otherwise |
180 | */ |
181 | static Boolean_t readBytes(wbxmlScannerPrivPtr_t pScanner, Long_t bytes); |
182 | |
183 | /** |
184 | * Decodes multi-byte integers. |
185 | * |
186 | * @pre pScanner->pos points to the first byte of the mb_int. |
187 | * @post pScanner->pos points to the last byte of the mb_int. |
188 | */ |
189 | static Ret_t parseInt(wbxmlScannerPrivPtr_t pScanner, MBINT *mbi); |
190 | |
191 | /** |
192 | * wbxmlHeader, wbxmlVersion, wbxmlPublicID, wbxmlCharset |
193 | * |
194 | * These functions are used for decoding the WBXML document header. |
195 | * wbxmlHeader is a short wrapper that calls the other four functions in |
196 | * the right order to scan the header. wbxmlStrtbl makes a copy of the |
197 | * string table. |
198 | */ |
199 | static Ret_t wbxmlHeader(wbxmlScannerPrivPtr_t pScanner); |
200 | static Ret_t wbxmlVersion(wbxmlScannerPrivPtr_t pScanner); |
201 | static Ret_t wbxmlPublicID(wbxmlScannerPrivPtr_t pScanner); |
202 | static Ret_t wbxmlCharset(wbxmlScannerPrivPtr_t pScanner); |
203 | static Ret_t wbxmlStrtbl(wbxmlScannerPrivPtr_t pScanner); |
204 | |
205 | /** |
206 | * Switch WBXML code page |
207 | */ |
208 | static Ret_t wbxmlSwitchPage(wbxmlScannerPrivPtr_t pScanner); |
209 | |
210 | /** |
211 | * wbxmlXXXToken |
212 | * |
213 | * Scan the document for the next valid XML/WBXML token as defined in the |
214 | * XLTDecCom header file (e.g. TOK_TAG_START). |
215 | * |
216 | * @pre pScanner->pos points to the first byte of a valid WBXML |
217 | * element (String, Tag, etc.) |
218 | * @post pScanner->pos points to the last byte of the WBXML element; |
219 | * pScanner->curtok contains type and tagid or pcdata of the token |
220 | */ |
221 | static Ret_t wbxmlStringToken(wbxmlScannerPrivPtr_t pScanner); |
222 | static Ret_t wbxmlOpaqueToken(wbxmlScannerPrivPtr_t pScanner); |
223 | static Ret_t wbxmlTagToken(wbxmlScannerPrivPtr_t pScanner); |
224 | |
225 | /** |
226 | * wbxmlSkipXXX |
227 | * |
228 | * WBXML extensions, entities, processing instructions and attributes are |
229 | * not supported by this scanner. If one is found it is skipped and |
230 | * processing continues afterwards. |
231 | */ |
232 | static Ret_t wbxmlSkipExtension(wbxmlScannerPrivPtr_t pScanner); |
233 | static Ret_t wbxmlSkipEntity(wbxmlScannerPrivPtr_t pScanner); |
234 | static Ret_t wbxmlSkipPI(wbxmlScannerPrivPtr_t); |
235 | static Ret_t wbxmlSkipAttribute(wbxmlScannerPrivPtr_t); |
236 | |
237 | /*************************************************************************/ |
238 | /* External Functions */ |
239 | /*************************************************************************/ |
240 | |
241 | /* |
242 | * Create and initialize a new WBXML scanner. Description see XLTDec.h. |
243 | */ |
244 | Ret_t |
245 | xltDecWbxmlInit(const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, |
246 | XltDecScannerPtr_t *ppScanner) |
247 | { |
248 | wbxmlScannerPrivPtr_t pScanner; |
249 | Ret_t rc; |
250 | |
251 | /* initialize new WBXML scanner */ |
252 | if ((pScanner = (wbxmlScannerPrivPtr_t)smlLibMalloc(sizeof(wbxmlScannerPriv_t))) == NULL((void*)0)) |
253 | return SML_ERR_NOT_ENOUGH_SPACE0x11; |
254 | smlLibMemset(pScanner, 0, sizeof(wbxmlScannerPriv_t)); |
255 | pScanner->bufend = pBufEnd; |
256 | pScanner->pos = *ppBufPos; |
257 | if ((pScanner->curtok = (XltDecTokenPtr_t)smlLibMalloc(sizeof(XltDecToken_t))) == NULL((void*)0)) { |
258 | smlLibFree(pScanner); |
259 | *ppScanner = NULL((void*)0); |
260 | return SML_ERR_NOT_ENOUGH_SPACE0x11; |
261 | } |
262 | smlLibMemset(pScanner->curtok, 0, sizeof(XltDecToken_t)); |
263 | if ((rc = xltUtilCreateStack(&pScanner->tagstack, 10)) != SML_ERR_OK0x00) { |
264 | smlLibFree(pScanner->curtok); |
265 | smlLibFree(pScanner); |
266 | *ppScanner = NULL((void*)0); |
267 | return rc; |
268 | } |
269 | pScanner->state = TAG_STATE0; |
270 | |
271 | /* point public/private methods to the right implementation */ |
272 | pScanner->nextTok = _nextTok; |
273 | pScanner->destroy = _destroy; |
274 | pScanner->pushTok = _pushTok; |
275 | pScanner->setBuf = _setBuf; |
276 | pScanner->getPos = _getPos; |
277 | |
278 | /* decode WBXML header */ |
279 | if ((rc = wbxmlHeader(pScanner)) != SML_ERR_OK0x00) { |
280 | pScanner->destroy((XltDecScannerPtr_t)pScanner); |
281 | *ppScanner = NULL((void*)0); |
282 | return rc; |
283 | } |
284 | |
285 | *ppScanner = (XltDecScannerPtr_t)pScanner; |
286 | |
287 | return SML_ERR_OK0x00; |
288 | } |
289 | |
290 | /** |
291 | * Free memory. Description see XltDecAll.h. |
292 | */ |
293 | static Ret_t |
294 | _destroy(XltDecScannerPtr_t pScanner) |
295 | { |
296 | wbxmlScannerPrivPtr_t pScannerPriv; |
297 | |
298 | if (pScanner == NULL((void*)0)) |
299 | return SML_ERR_OK0x00; |
300 | |
301 | pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; |
302 | if (pScannerPriv->tagstack != NULL((void*)0)) |
303 | pScannerPriv->tagstack->destroy(pScannerPriv->tagstack); |
304 | smlLibFree(pScannerPriv->curtok); |
305 | smlLibFree(pScannerPriv->strtbl); |
306 | smlLibFree(pScannerPriv); |
307 | |
308 | return SML_ERR_OK0x00; |
309 | } |
310 | |
311 | /** |
312 | * Get next token. |
313 | */ |
314 | static Ret_t |
315 | _nextTok(XltDecScannerPtr_t pScanner) |
316 | { |
317 | wbxmlScannerPrivPtr_t pScannerPriv; |
318 | Ret_t rc; |
319 | |
320 | pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; |
321 | // T.K.: chanched Ptr_t to _t |
322 | smlLibMemset(pScanner->curtok, 0, sizeof(XltDecToken_t)); |
323 | pScannerPriv->curtok->start = pScannerPriv->pos; |
324 | |
325 | /* keep going until we find a "supported" element */ |
326 | rc = SML_ERR_OK0x00; |
327 | while (rc == SML_ERR_OK0x00) { |
328 | /* skip PIs, extensions and entities... */ |
329 | if (IS_PI(pScannerPriv->pos)(*(pScannerPriv->pos) == 0x43)) { |
330 | rc = wbxmlSkipPI(pScannerPriv); |
331 | } else if (IS_EXTENSION(pScannerPriv->pos)(((*(pScannerPriv->pos) == 0x40) || (*(pScannerPriv->pos ) == 0x41) || (*(pScannerPriv->pos) == 0x42)) || ((*(pScannerPriv ->pos) == 0x80) || (*(pScannerPriv->pos) == 0x81) || (* (pScannerPriv->pos) == 0x82)) || ((*(pScannerPriv->pos) == 0xC0) || (*(pScannerPriv->pos) == 0xC1) || (*(pScannerPriv ->pos) == 0xC2)))) { |
332 | rc = wbxmlSkipExtension(pScannerPriv); |
333 | } else if (IS_ENTITY(pScannerPriv->pos)(*(pScannerPriv->pos) == 0x02)) { |
334 | rc = wbxmlSkipEntity(pScannerPriv); |
335 | |
336 | /* ... decode strings, opaque data and tags */ |
337 | } else if (IS_STRING(pScannerPriv->pos)((*(pScannerPriv->pos) == 0x03) || (*(pScannerPriv->pos ) == 0x83))) { |
338 | rc = wbxmlStringToken(pScannerPriv); |
339 | break; |
340 | } else if (IS_OPAQUE(pScannerPriv->pos)(*(pScannerPriv->pos) == 0xC3)) { |
341 | rc = wbxmlOpaqueToken(pScannerPriv); |
342 | break; |
343 | } else { |
344 | rc = wbxmlTagToken(pScannerPriv); |
345 | break; |
346 | } |
347 | } |
348 | |
349 | return rc; |
350 | } |
351 | |
352 | /** |
353 | * Reset the scanner to the starting position of the current token within |
354 | * the buffer. |
355 | */ |
356 | static Ret_t |
357 | _pushTok(XltDecScannerPtr_t pScanner) |
358 | { |
359 | wbxmlScannerPrivPtr_t pScannerPriv; |
360 | XltUtilStackPtr_t pTagStack; |
361 | XltTagID_t tagid; |
362 | Ret_t rc = 0; |
363 | |
364 | pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; |
365 | pTagStack = pScannerPriv->tagstack; |
366 | |
367 | if (pScannerPriv->curtok->start == NULL((void*)0)) |
368 | return SML_ERR_WRONG_USAGE0x13; |
369 | |
370 | /* reset scanner to position where tok begins */ |
371 | pScannerPriv->pos = pScannerPriv->curtok->start; |
372 | |
373 | /* correct the tag stack */ |
374 | if (pScannerPriv->curtok->type == TOK_TAG_START) { |
375 | rc = pTagStack->pop(pTagStack, &tagid); |
376 | } else if (pScannerPriv->curtok->type == TOK_TAG_END) { |
377 | tagid = pScannerPriv->curtok->tagid; |
378 | rc = pTagStack->push(pTagStack, tagid); |
379 | } |
380 | if (rc) return rc; |
381 | |
382 | /* invalidate curtok */ |
383 | /* T.K. Possible Error. pScannerPriv->curtok is of type XltDecToken_t NOT ...Ptr_t */ |
384 | // OrigLine: |
385 | // smlLibMemset(pScannerPriv->curtok, 0, sizeof(XltDecTokenPtr_t)); |
386 | pScannerPriv->curtok->type = (XltTokType_t)0; |
387 | |
388 | return SML_ERR_OK0x00; |
389 | } |
390 | |
391 | static void |
392 | _setBuf(XltDecScannerPtr_t pScanner, const MemPtr_t pBufStart, |
393 | const MemPtr_t pBufEnd) |
394 | { |
395 | wbxmlScannerPrivPtr_t pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; |
396 | pScannerPriv->pos = pBufStart; |
397 | pScannerPriv->bufend = pBufEnd; |
398 | } |
399 | |
400 | static MemPtr_t |
401 | _getPos(XltDecScannerPtr_t pScanner, Long_t *remaining) |
402 | { |
403 | if (remaining) |
404 | *remaining = ((wbxmlScannerPrivPtr_t)pScanner)->bufend - ((wbxmlScannerPrivPtr_t)pScanner)->pos; |
405 | return ((wbxmlScannerPrivPtr_t)pScanner)->pos; |
406 | } |
407 | |
408 | /*************************************************************************/ |
409 | /* Internal Functions */ |
410 | /*************************************************************************/ |
411 | |
412 | /* |
413 | * Advance the position pointer. Description see above. |
414 | */ |
415 | static Boolean_t |
416 | readBytes(wbxmlScannerPrivPtr_t pScanner, Long_t bytes) |
417 | { |
418 | if (pScanner->pos + bytes > pScanner->bufend) { |
419 | pScanner->finished = 1; |
420 | return 0; |
421 | } |
422 | pScanner->pos += bytes; |
423 | return 1; |
424 | } |
425 | |
426 | /* |
427 | * NOTICE: Entities, Extensions, Processing Instructions and Attributes |
428 | * are not supported by the WBXML scanner. |
429 | * |
430 | * Extensions and Attributes are document-specific and are as such not used |
431 | * by the SyncML specification. |
432 | * The scanner will just ignore and skip over them. Neither |
433 | * this scanner nor the parser use processing instructions so they are |
434 | * skipped as well. |
435 | */ |
436 | |
437 | /* |
438 | * Decode the WBXML header containing version number, document public |
439 | * identifier, character set and a string table. |
440 | */ |
441 | static Ret_t |
442 | wbxmlHeader(wbxmlScannerPrivPtr_t pScanner) |
443 | { |
444 | Ret_t rc; |
445 | |
446 | /* decode the WBXML header */ |
447 | if ((rc = wbxmlVersion(pScanner)) != SML_ERR_OK0x00) |
448 | return rc; |
449 | if ((rc = wbxmlPublicID(pScanner)) != SML_ERR_OK0x00) |
450 | return rc; |
451 | if ((rc = wbxmlCharset(pScanner)) != SML_ERR_OK0x00) |
452 | return rc; |
453 | if ((rc = wbxmlStrtbl(pScanner)) != SML_ERR_OK0x00) |
454 | return rc; |
455 | return SML_ERR_OK0x00; |
456 | } |
457 | |
458 | /** |
459 | * Decode WBXML version. The scanner returns an error if the major version |
460 | * of the document differs from the major version this scanner supports or |
461 | * if the minor version of the document is larger than the minor version |
462 | * the scanner supports. |
463 | */ |
464 | static Ret_t |
465 | wbxmlVersion(wbxmlScannerPrivPtr_t pScanner) |
466 | { |
467 | Byte_t major, minor; |
468 | |
469 | minor = ((Byte_t)(*pScanner->pos & 0x0F)); |
470 | major = ((Byte_t)((*pScanner->pos >> 4) + 1)); |
471 | |
472 | if (major != _MAJOR_VERSION1 || minor > _MAX_PARSER_MINOR_VERSION3) |
473 | return SML_DECODEERROR(SML_ERR_XLT_INCOMP_WBXML_VERS,pScanner,"wbxmlVersion")show_decode_error(0x200A,(XltDecScannerPtr_t)pScanner,"wbxmlVersion" ); |
474 | |
475 | if (!readBytes(pScanner, 1)) |
476 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlVersion")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlVersion" ); |
477 | |
478 | return SML_ERR_OK0x00; |
479 | } |
480 | |
481 | /** |
482 | * Decodes WBXML Document Public Identifier. |
483 | */ |
484 | static Ret_t |
485 | wbxmlPublicID(wbxmlScannerPrivPtr_t pScanner) |
486 | { |
487 | MBINT tmp; |
488 | Ret_t rc; |
489 | |
490 | if (*pScanner->pos != 0) { |
491 | /* pre-defined numeric identifier */ |
492 | if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK0x00) |
493 | return rc; |
494 | pScanner->pubID = tmp; |
495 | pScanner->pubIDIdx = 0; |
496 | } else { |
497 | /* public id is given as string table entry (which we |
498 | haven't read at this point so we'll save the reference |
499 | for later) */ |
500 | if (!readBytes(pScanner, 1)) |
501 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlPublicID")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlPublicID" ); |
502 | if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK0x00) |
503 | return rc; |
504 | pScanner->pubID = 0; |
505 | pScanner->pubIDIdx = tmp; |
506 | } |
507 | if (!readBytes(pScanner, 1)) |
508 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlPublicID")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlPublicID" ); |
509 | return SML_ERR_OK0x00; |
510 | } |
511 | |
512 | /** |
513 | * Decode WBXML Charset. |
514 | */ |
515 | static Ret_t |
516 | wbxmlCharset(wbxmlScannerPrivPtr_t pScanner) |
517 | { |
518 | /* TODO: if charset iformation has to be processed |
519 | it can be done here. For the moment only UTF-8 is used by SyncML */ |
520 | MBINT mibenum; |
521 | Ret_t rc; |
522 | |
523 | /* charset is given as a single IANA assigned MIBEnum value */ |
524 | if ((rc = parseInt(pScanner, &mibenum)) != SML_ERR_OK0x00) |
525 | return rc; |
526 | pScanner->charset = mibenum; |
527 | |
528 | if (!readBytes(pScanner, 1)) |
529 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlCharset")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlCharset" ); |
530 | |
531 | return SML_ERR_OK0x00; |
532 | } |
533 | |
534 | /** |
535 | * Keep a copy of the string table. |
536 | */ |
537 | static Ret_t |
538 | wbxmlStrtbl(wbxmlScannerPrivPtr_t pScanner) |
539 | { |
540 | MBINT len; |
541 | Ret_t rc; |
542 | |
543 | if ((rc = parseInt(pScanner, &len)) != SML_ERR_OK0x00) |
544 | return rc; |
545 | if (!readBytes(pScanner, 1)) |
546 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlStrtbl")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlStrtbl" ); |
547 | pScanner->strtbllen = len; |
548 | if (len > 0) { |
549 | if (pScanner->pos + len > pScanner->bufend) |
550 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlStrtbl")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlStrtbl" ); |
551 | if ((pScanner->strtbl = smlLibMalloc(len)) == NULL((void*)0)) |
552 | { |
553 | return SML_ERR_NOT_ENOUGH_SPACE0x11; |
554 | } |
555 | smlLibMemcpy(pScanner->strtbl, pScanner->pos, len); |
556 | readBytes(pScanner, len); |
557 | } else { |
558 | pScanner->strtbl = NULL((void*)0); |
559 | } |
560 | |
561 | /* if the public ID was given as a string table reference save a |
562 | reference to the corresponding string for later */ |
563 | if (pScanner->pubID == 0) { |
564 | if (pScanner->pubIDIdx > pScanner->strtbllen) |
565 | return SML_DECODEERROR(SML_ERR_XLT_INVAL_WBXML_DOC,pScanner,"wbxmlStrtbl")show_decode_error(0x200E,(XltDecScannerPtr_t)pScanner,"wbxmlStrtbl" ); |
566 | pScanner->pubIDStr = (String_t)(pScanner->strtbl + pScanner->pubIDIdx); |
567 | } |
568 | |
569 | return SML_ERR_OK0x00; |
570 | } |
571 | |
572 | static Ret_t |
573 | parseInt(wbxmlScannerPrivPtr_t pScanner, MBINT *mbi) |
574 | { |
575 | *mbi = 0; |
576 | /* accumulate byte value until continuation flag (MSB) is zero */ |
577 | for (;;) { |
578 | *mbi = *mbi << 7; |
579 | *mbi += *(pScanner->pos) & 0x7F; |
580 | if (!(*pScanner->pos & 0x80)) break; |
581 | if (!readBytes(pScanner, 1)) |
582 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"parseInt")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"parseInt" ); |
583 | } |
584 | return SML_ERR_OK0x00; |
585 | } |
586 | |
587 | static Ret_t |
588 | wbxmlStringToken(wbxmlScannerPrivPtr_t pScanner) |
589 | { |
590 | SmlPcdataPtr_t pPcdata; |
591 | Ret_t rc; |
592 | |
593 | if ((pPcdata = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL((void*)0)) |
594 | return SML_ERR_NOT_ENOUGH_SPACE0x11; |
595 | /* copy the string into the new PCdata struct */ |
596 | if (IS_STR_I(pScanner->pos)(*(pScanner->pos) == 0x03)) { |
597 | /* inline string */ |
598 | if (!readBytes(pScanner, 1)) |
599 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlStringToken")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlStringToken" ); |
600 | pPcdata->extension = SML_EXT_UNDEFINED; |
601 | pPcdata->contentType = SML_PCDATA_STRING; |
602 | pPcdata->length = smlLibStrlen((String_t)pScanner->pos); |
603 | if (pScanner->pos + pPcdata->length + 1 > pScanner->bufend) { |
604 | smlLibFree(pPcdata); |
605 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlStringToken")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlStringToken" ); |
606 | } |
607 | if ((pPcdata->content = smlLibMalloc(pPcdata->length + 1)) == NULL((void*)0)) { |
608 | smlLibFree(pPcdata); |
609 | return SML_ERR_NOT_ENOUGH_SPACE0x11; |
610 | } |
611 | smlLibStrncpy(pPcdata->content, (String_t)pScanner->pos, pPcdata->length + 1); |
612 | readBytes(pScanner, pPcdata->length + 1); |
613 | |
614 | } else { |
615 | /* string table reference */ |
616 | MBINT offset; /* offset into string table */ |
617 | if (!readBytes(pScanner, 1)) |
618 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlStringToken")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlStringToken" ); |
619 | if ((rc = parseInt(pScanner, &offset)) != SML_ERR_OK0x00) { |
620 | smlLibFree(pPcdata); |
621 | return rc; |
622 | } |
623 | if (offset >= pScanner->strtbllen) { |
624 | smlLibFree(pPcdata); |
625 | return SML_DECODEERROR(SML_ERR_XLT_INVAL_WBXML_DOC,pScanner,"wbxmlStringToken")show_decode_error(0x200E,(XltDecScannerPtr_t)pScanner,"wbxmlStringToken" ); |
626 | } |
627 | pPcdata->contentType = SML_PCDATA_STRING; |
628 | pPcdata->length = smlLibStrlen((String_t)(pScanner->strtbl + offset)); |
629 | if ((pPcdata->content = smlLibMalloc(pPcdata->length + 1)) == NULL((void*)0)) { |
630 | smlLibFree(pPcdata); |
631 | return SML_ERR_NOT_ENOUGH_SPACE0x11; |
632 | } |
633 | smlLibStrncpy(pPcdata->content, (String_t)(pScanner->strtbl + offset), pPcdata->length + 1); |
634 | readBytes(pScanner, 1); |
635 | } |
636 | |
637 | pScanner->curtok->pcdata = pPcdata; |
638 | |
639 | pScanner->curtok->type = TOK_CONT; |
640 | |
641 | return SML_ERR_OK0x00; |
642 | } |
643 | |
644 | static Ret_t |
645 | wbxmlOpaqueToken(wbxmlScannerPrivPtr_t pScanner) |
646 | { |
647 | SmlPcdataPtr_t pPcdata = NULL((void*)0); |
648 | MBINT len; |
649 | Ret_t rc; |
650 | |
651 | if (!readBytes(pScanner, 1)) |
652 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlOpaqueToken")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlOpaqueToken" ); |
653 | |
654 | /* a mbi indicates the length of the opaque data block that we'll |
655 | copy into new PCdata struct */ |
656 | if ((rc = parseInt(pScanner, &len)) != SML_ERR_OK0x00) |
657 | return rc; |
658 | if (!readBytes(pScanner, 1)) |
659 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlOpaqueToken")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlOpaqueToken" ); |
660 | if (pScanner->pos + len > pScanner->bufend) |
661 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlOpaqueToken")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlOpaqueToken" ); |
662 | if ((pPcdata = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL((void*)0)) |
663 | return SML_ERR_NOT_ENOUGH_SPACE0x11; |
664 | pPcdata->extension = SML_EXT_UNDEFINED; |
665 | pPcdata->contentType = SML_PCDATA_OPAQUE; |
666 | pPcdata->length = len; |
667 | /* Modification 2001-07-03 by Luz %%%%%: |
668 | * made sure that content is one null byte longer |
669 | * than indicated opaque content, such that strings that are coded as |
670 | * opaque (happens to be the case with Nokia 9210) can still be read |
671 | * as C-string without need for an intermediate buffer |
672 | */ |
673 | /* original: |
674 | if ((pPcdata->content = smlLibMalloc(len)) == NULL) { |
675 | smlLibFree(pPcdata); |
676 | return SML_ERR_NOT_ENOUGH_SPACE; |
677 | } |
678 | */ |
679 | /* modified: */ |
680 | if ((pPcdata->content = smlLibMalloc(len+1)) == NULL((void*)0)) { |
681 | smlLibFree(pPcdata); |
682 | return SML_ERR_NOT_ENOUGH_SPACE0x11; |
683 | } |
684 | ((char *)pPcdata->content)[len]=0; /* make sure there is a c-string terminator */ |
685 | /* end modification */ |
686 | |
687 | smlLibMemcpy(pPcdata->content, pScanner->pos, len); |
688 | pScanner->curtok->pcdata = pPcdata; |
689 | |
690 | readBytes(pScanner, len); |
691 | |
692 | pScanner->curtok->type = TOK_CONT; |
693 | |
694 | return SML_ERR_OK0x00; |
695 | } |
696 | |
697 | static Ret_t |
698 | wbxmlTagToken(wbxmlScannerPrivPtr_t pScanner) |
699 | { |
700 | XltTagID_t tagid; |
701 | Boolean_t has_cont, has_attr; |
702 | Ret_t rc; |
703 | |
704 | if (IS_SWITCH(pScanner->pos)(*(pScanner->pos) == 0x00)) { |
705 | if ((rc = wbxmlSwitchPage(pScanner)) != SML_ERR_OK0x00) |
706 | return rc; |
707 | } |
708 | |
709 | /* we have to look at the top of the tagstack to see which |
710 | start tag an end tag belongs to */ |
711 | if (IS_END(pScanner->pos)(*(pScanner->pos) == 0x01)) { |
712 | if (!readBytes(pScanner, 1)) |
713 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlTagToken")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlTagToken" ); |
714 | pScanner->curtok->type = TOK_TAG_END; |
715 | rc = pScanner->tagstack->pop(pScanner->tagstack, &tagid); |
716 | if (rc == SML_ERR_WRONG_USAGE0x13) |
717 | return SML_DECODEERROR(SML_ERR_XLT_INVAL_WBXML_DOC,pScanner,"wbxmlTagToken")show_decode_error(0x200E,(XltDecScannerPtr_t)pScanner,"wbxmlTagToken" ); |
718 | else if (rc) |
719 | return rc; |
720 | pScanner->curtok->tagid = tagid; |
721 | return SML_ERR_OK0x00; |
722 | } |
723 | |
724 | |
725 | /* look at the two MSB: does this tag have content or attributes? */ |
726 | |
727 | has_cont = ((Boolean_t)(HAS_CONTENT(pScanner->pos)(*pScanner->pos & 0x40))); |
728 | has_attr = ((Boolean_t)(HAS_ATTRIBUTES(pScanner->pos)(*pScanner->pos & 0x80))); |
729 | |
730 | |
731 | /* look up tag ID either by string or by number */ |
732 | if (IS_LITERAL(pScanner->pos)((*pScanner->pos & 0x3F) == 0x04)) { |
733 | MBINT offset; /* offset into the string table */ |
734 | if (!readBytes(pScanner, 1)) |
735 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlTagToken")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlTagToken" ); |
736 | if ((rc = parseInt(pScanner, &offset)) != SML_ERR_OK0x00) |
737 | return rc; |
738 | if (offset > pScanner->strtbllen) |
739 | return SML_DECODEERROR(SML_ERR_XLT_INVAL_WBXML_DOC,pScanner,"wbxmlTagToken")show_decode_error(0x200E,(XltDecScannerPtr_t)pScanner,"wbxmlTagToken" ); |
740 | |
741 | rc = (Ret_t)getTagIDByStringAndExt((String_t)(pScanner->strtbl + offset), pScanner->activeExt, &tagid); |
742 | if ((tagid == TN_UNDEF) || (rc != SML_ERR_OK0x00)) return rc; |
743 | |
744 | } else { |
745 | rc = (Ret_t)getTagIDByByteAndExt((Byte_t)IDENTITY(pScanner->pos)(*pScanner->pos & 0x3F), pScanner->activeExt, &tagid); |
746 | if ((tagid == TN_UNDEF) || (rc != SML_ERR_OK0x00)) return rc; |
747 | |
748 | } |
749 | |
750 | /* we know everything we need to know */ |
751 | pScanner->curtok->tagid = tagid; |
752 | pScanner->curtok->type = has_cont ? TOK_TAG_START : TOK_TAG_EMPTY; |
753 | #ifdef __USE_METINF__ |
754 | pScanner->curtok->ext = pScanner->cptag == 0 ? SML_EXT_UNDEFINED : SML_EXT_METINF; |
755 | #else |
756 | pScanner->curtok->ext = SML_EXT_UNDEFINED; |
757 | #endif |
758 | |
759 | if (!readBytes(pScanner, 1)) |
760 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlTagToken")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlTagToken" ); |
761 | |
762 | /* push tag onto tagstack unless this tag is empty */ |
763 | if (has_cont) { |
764 | if ((rc = pScanner->tagstack->push(pScanner->tagstack, tagid)) != SML_ERR_OK0x00) |
765 | return rc; |
766 | } |
767 | |
768 | /* skip attributes */ |
769 | if (has_attr) { |
770 | pScanner->state = ATTRIBUTE_STATE1; |
771 | if ((rc = wbxmlSkipAttribute(pScanner)) != SML_ERR_OK0x00) |
772 | return rc; |
773 | pScanner->state = TAG_STATE0; |
774 | } |
775 | |
776 | return SML_ERR_OK0x00; |
777 | } |
778 | |
779 | /* |
780 | * Switch WBXML code page. |
781 | */ |
782 | /* T.K. 06.02.01 |
783 | * We need to enhance this as soon as we introduce |
784 | * Sub DTD's with more than one WBXML codepage. But till then |
785 | * there is only one case where WBXML codepages can occure, and |
786 | * this is the MetInf Sub DTD. So in case we find a codepage switch |
787 | * to something other than codepage zero, we set the active extension |
788 | * to metinf. |
789 | * In future versions the pScanner needs to be enhanced, to translate |
790 | * codepageswitches context sensitive to the active extension. |
791 | */ |
792 | static Ret_t |
793 | wbxmlSwitchPage(wbxmlScannerPrivPtr_t pScanner) |
794 | { |
795 | if (!readBytes(pScanner, 1)) |
796 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSwitchPage")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSwitchPage" ); |
797 | if (pScanner->state == TAG_STATE0) |
798 | pScanner->cptag = (SmlPcdataExtension_t)*pScanner->pos; |
799 | else |
800 | pScanner->cpattr = *pScanner->pos; |
801 | readBytes(pScanner, 1); |
802 | /* T.K. this needs to be adjusted as described above */ |
803 | if (pScanner->cpattr != 0 || pScanner->cptag != 0) |
804 | pScanner->activeExt = SML_EXT_METINF; |
805 | else |
806 | pScanner->activeExt = SML_EXT_UNDEFINED; |
807 | return SML_ERR_OK0x00; |
808 | } |
809 | |
810 | |
811 | /******************************/ |
812 | /* Unsupported WBXML elements */ |
813 | /******************************/ |
814 | |
815 | /** |
816 | * Skips entities but doesn't do anything useful yet. |
817 | */ |
818 | static Ret_t |
819 | wbxmlSkipEntity(wbxmlScannerPrivPtr_t pScanner) |
820 | { |
821 | MBINT tmp; |
822 | Ret_t rc; |
823 | |
824 | if (!readBytes(pScanner, 1)) |
825 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipEntity")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSkipEntity" ); |
826 | if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK0x00) |
827 | return rc; |
828 | if (!readBytes(pScanner, 1)) |
829 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipEntity")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSkipEntity" ); |
830 | |
831 | return SML_ERR_OK0x00; |
832 | } |
833 | |
834 | |
835 | /* |
836 | * Decode WBXML extensions. Skips the extension but doesn't do anything |
837 | * useful with it. |
838 | */ |
839 | static Ret_t |
840 | wbxmlSkipExtension(wbxmlScannerPrivPtr_t pScanner) |
841 | { |
842 | MBINT tmp; |
843 | Ret_t rc; |
844 | |
845 | if (IS_EXT(pScanner->pos)((*(pScanner->pos) == 0xC0) || (*(pScanner->pos) == 0xC1 ) || (*(pScanner->pos) == 0xC2))) { |
846 | /* single byte extension token */ |
847 | if (!readBytes(pScanner, 1)) |
848 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipExtension")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSkipExtension" ); |
849 | } else if (IS_EXT_I(pScanner->pos)((*(pScanner->pos) == 0x40) || (*(pScanner->pos) == 0x41 ) || (*(pScanner->pos) == 0x42))) { |
850 | /* inline string extension token */ |
851 | if (!readBytes(pScanner, 1)) |
852 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipExtension")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSkipExtension" ); |
853 | if (!readBytes(pScanner, smlLibStrlen((String_t)pScanner->pos) + 1)) |
854 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipExtension")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSkipExtension" ); |
855 | } else { |
856 | /* inline integer extension token */ |
857 | if (!readBytes(pScanner, 1)) |
858 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipExtension")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSkipExtension" ); |
859 | if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK0x00) |
860 | return rc; |
861 | if (!readBytes(pScanner, tmp + 1)) |
862 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipExtension")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSkipExtension" ); |
863 | } |
864 | return SML_ERR_OK0x00; |
865 | } |
866 | |
867 | /* |
868 | * Handle XML processing instructions. PIs are not supported but the |
869 | * scanner recognizes and skips over them. |
870 | */ |
871 | static Ret_t |
872 | wbxmlSkipPI(wbxmlScannerPrivPtr_t pScanner) |
873 | { |
874 | /* PIs are just like tag attributes with a special PI token instead |
875 | * of the attribute start token */ |
876 | return wbxmlSkipAttribute(pScanner); |
877 | } |
878 | |
879 | /* |
880 | * Handle attributes. Attributes are not supported but the |
881 | * scanner recognizes and skips over them. |
882 | */ |
883 | static Ret_t |
884 | wbxmlSkipAttribute(wbxmlScannerPrivPtr_t pScanner) |
885 | { |
886 | XltDecTokenPtr_t oldtok; |
887 | MBINT tmp; |
888 | Ret_t rc = 0; |
889 | |
890 | /* skipping attributes shouldn't change the current token so we |
891 | make a copy... */ |
892 | if ((oldtok = (XltDecTokenPtr_t)smlLibMalloc(sizeof(XltDecToken_t))) == NULL((void*)0)) |
893 | return SML_ERR_NOT_ENOUGH_SPACE0x11; |
894 | smlLibMemcpy(oldtok, pScanner->curtok, sizeof(XltDecToken_t)); |
895 | |
896 | /* ... skip until attribute end tag... */ |
897 | while (!IS_END(pScanner->pos)(*(pScanner->pos) == 0x01)) { |
898 | if (IS_STRING(pScanner->pos)((*(pScanner->pos) == 0x03) || (*(pScanner->pos) == 0x83 ))) { |
899 | rc = wbxmlStringToken(pScanner); |
900 | /* avoid memory leak due to this ugly workaround of |
901 | skipping attributes */ |
902 | smlLibFree(pScanner->curtok->pcdata); |
903 | } else if (IS_EXTENSION(pScanner->pos)(((*(pScanner->pos) == 0x40) || (*(pScanner->pos) == 0x41 ) || (*(pScanner->pos) == 0x42)) || ((*(pScanner->pos) == 0x80) || (*(pScanner->pos) == 0x81) || (*(pScanner->pos ) == 0x82)) || ((*(pScanner->pos) == 0xC0) || (*(pScanner-> pos) == 0xC1) || (*(pScanner->pos) == 0xC2)))) { |
904 | rc = wbxmlSkipExtension(pScanner); |
905 | } else if (IS_ENTITY(pScanner->pos)(*(pScanner->pos) == 0x02)) { |
906 | rc = wbxmlSkipEntity(pScanner); |
907 | } else if (IS_OPAQUE(pScanner->pos)(*(pScanner->pos) == 0xC3)) { |
908 | rc = wbxmlOpaqueToken(pScanner); |
909 | /* avoid memory leak due to this ugly workaround of |
910 | skipping attributes */ |
911 | smlLibFree(pScanner->curtok->pcdata); |
912 | } else if (IS_LITERAL(pScanner->pos)((*pScanner->pos & 0x3F) == 0x04)) { |
913 | if (!readBytes(pScanner, 1)) |
914 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipAttribute")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSkipAttribute" ); |
915 | rc = parseInt(pScanner, &tmp); |
916 | if (!readBytes(pScanner, 1)) |
917 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipAttribute")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSkipAttribute" ); |
918 | } else if (IS_SWITCH(pScanner->pos)(*(pScanner->pos) == 0x00)) { |
919 | rc = wbxmlSwitchPage(pScanner); |
920 | } else { |
921 | if (!readBytes(pScanner, 1)) |
922 | return SML_DECODEERROR(SML_ERR_XLT_END_OF_BUFFER,pScanner,"wbxmlSkipAttribute")show_decode_error(0x2012,(XltDecScannerPtr_t)pScanner,"wbxmlSkipAttribute" ); |
923 | } |
924 | |
925 | if (rc != SML_ERR_OK0x00) { |
926 | smlLibFree(oldtok); |
927 | return rc; |
928 | } |
929 | |
930 | } |
931 | /* ... then skip the end tag itself... */ |
932 | readBytes(pScanner, 1); |
933 | |
934 | /* ... and finaly restore our copy of curtok */ |
935 | smlLibMemcpy(pScanner->curtok, oldtok, sizeof(XltDecToken_t)); |
936 | smlLibFree(oldtok); |
937 | |
938 | return SML_ERR_OK0x00; |
939 | } |
940 | |
941 | #ifdef __USE_EXTENSIONS__ |
942 | /* |
943 | * This function tries to decode an inlined WBXML document inside |
944 | * an PCDATA element. |
945 | * In case of failing to decode it the PCDATA element isn't changed |
946 | * at all. |
947 | */ |
948 | |
949 | void |
950 | subdtdDecodeWbxml(XltDecoderPtr_t pDecoder,SmlPcdataPtr_t *ppPcdata) { |
951 | Ret_t _err = SML_ERR_OK0x00; |
952 | MemPtr_t pSubBuf = NULL((void*)0); |
953 | SmlPcdataPtr_t pSubPcdata = NULL((void*)0); |
954 | XltDecoderPtr_t pSubDecoder = NULL((void*)0); |
955 | #ifdef __USE_DEVINF__ |
956 | wbxmlScannerPrivPtr_t pScannerPriv = NULL((void*)0); |
957 | #endif |
958 | |
959 | /* some sanity checks at first */ |
960 | |
961 | if (*ppPcdata == NULL((void*)0)) { |
962 | if (pDecoder) /* use this rare case to remove warning */ |
963 | { |
964 | } |
965 | return; |
966 | } |
967 | |
968 | if ((*ppPcdata)->contentType != SML_PCDATA_OPAQUE) return; |
969 | |
970 | // now create a sub buffer |
971 | pSubBuf = (MemPtr_t)smlLibMalloc((*ppPcdata)->length); |
972 | if (pSubBuf == NULL((void*)0)) return; |
973 | smlLibMemset(pSubBuf, 0x00, (*ppPcdata)->length); |
974 | smlLibMemmove(pSubBuf, (*ppPcdata)->content, (*ppPcdata)->length); |
975 | |
976 | /* ok looks fine sofar - now lets decode the rest */ |
977 | /* now lets create a decoder, but without parsing the SyncML |
978 | * start tags (because it's not there) and skip the XML |
979 | * part as we don't need it. |
980 | */ |
981 | pSubDecoder = (XltDecoderPtr_t)smlLibMalloc(sizeof(XltDecoder_t)); |
982 | if (pSubDecoder == NULL((void*)0)) { |
983 | smlLibFree(pSubBuf); |
984 | return; |
985 | } |
986 | pSubDecoder->finished = 0; |
987 | pSubDecoder->final = 0; |
988 | pSubDecoder->scanner = NULL((void*)0); |
989 | if (xltUtilCreateStack(&pSubDecoder->tagstack, 10) != SML_ERR_OK0x00) { |
990 | smlLibFree(pSubDecoder); |
991 | smlLibFree(pSubBuf); |
992 | return; |
993 | } |
994 | if (xltDecWbxmlInit(pSubBuf+(*ppPcdata)->length,&pSubBuf, &pSubDecoder->scanner) != SML_ERR_OK0x00) { |
995 | xltDecTerminate(pSubDecoder); |
996 | smlLibFree(pSubBuf); |
997 | return; |
998 | } |
999 | pSubDecoder->charset = pSubDecoder->scanner->charset; |
1000 | pSubDecoder->charsetStr = NULL((void*)0); |
1001 | |
1002 | pSubPcdata = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t)); |
1003 | if (pSubPcdata == NULL((void*)0)) { |
1004 | xltDecTerminate(pSubDecoder); |
1005 | smlLibFree(pSubPcdata); |
1006 | smlLibFree(pSubBuf); |
1007 | return; |
1008 | } |
1009 | /* T.K. |
1010 | * In the future we need to check the WBXML stringtable and |
1011 | * switch into the right Sub DTD. But sofar only DevInf is |
1012 | * supported so we can save time and space |
1013 | */ |
1014 | /* T.K. |
1015 | * To prevent buffer corruption when __USE_DEVINF__ is not used |
1016 | * we initialize _err with any errorcode != OK, and this way |
1017 | * force the function to exit without modifying the ppPcdata |
1018 | */ |
1019 | _err = SML_ERR_UNSPECIFIC0x10; |
Value stored to '_err' is never read | |
1020 | #ifdef __USE_DEVINF__ |
1021 | pSubPcdata->contentType = SML_PCDATA_EXTENSION; |
1022 | pSubPcdata->extension = SML_EXT_DEVINF; |
1023 | pSubPcdata->length = 0; |
1024 | pSubPcdata->content = NULL((void*)0); |
1025 | |
1026 | pScannerPriv = (wbxmlScannerPrivPtr_t)pSubDecoder->scanner; |
1027 | pScannerPriv->activeExt = SML_EXT_DEVINF; |
1028 | pScannerPriv->cpattr = 0; |
1029 | pScannerPriv->cptag = (SmlPcdataExtension_t)0; |
1030 | smlLibMemset(pScannerPriv->curtok, 0,sizeof(XltDecToken_t)); |
1031 | |
1032 | _err = buildDevInfDevInfCmd(pSubDecoder, (VoidPtr_t)&pSubPcdata->content); |
1033 | #endif |
1034 | |
1035 | if (_err != SML_ERR_OK0x00) { |
1036 | xltDecTerminate(pSubDecoder); |
1037 | smlLibFree(pSubPcdata); |
1038 | smlLibFree(pSubBuf); |
1039 | return; |
1040 | } |
1041 | |
1042 | /* parsing is done, now lets anchor it within the original PCDATA element */ |
1043 | smlFreePcdata(*ppPcdata); |
1044 | *ppPcdata = pSubPcdata; |
1045 | |
1046 | /* we are done */ |
1047 | xltDecTerminate(pSubDecoder); |
1048 | smlLibFree(pSubBuf); |
1049 | |
1050 | return; |
1051 | } |
1052 | |
1053 | #endif |
1054 | #endif |