1 /*************************************************************************/ 2 /* module: WBXML decoder */ 3 /* file: XLTDecWbxml.c */ 4 /* target system: all */ 5 /* target OS: all */ 6 /*************************************************************************/ 7 8 /* 9 * Copyright Notice 10 * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication 11 * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., 12 * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). 13 * All Rights Reserved. 14 * Implementation of all or part of any Specification may require 15 * licenses under third party intellectual property rights, 16 * including without limitation, patent rights (such a third party 17 * may or may not be a Supporter). The Sponsors of the Specification 18 * are not responsible and shall not be held responsible in any 19 * manner for identifying or failing to identify any or all such 20 * third party intellectual property rights. 21 * 22 * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED 23 * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, 24 * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, 25 * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML 26 * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING 27 * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION 28 * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 29 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 30 * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., 31 * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY 32 * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF 33 * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF 34 * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, 35 * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH 36 * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED 37 * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. 38 * 39 * The above notice and this paragraph must be included on all copies 40 * of this document that are made. 41 * 42 */ 43 44 /** 45 * The WBXML scanner/tokenizer. Used by the SyncML parser. 46 */ 47 48 49 #include <define.h> 50 #ifdef __SML_WBXML__ 51 /*************************************************************************/ 52 /* Definitions */ 53 /*************************************************************************/ 54 #include "xltdevinf.h" 55 #include "xltdmtnd.h" 56 #include "xltdeccom.h" 57 #include "xlttags.h" 58 #include "xltutilstack.h" 59 #include "xltdec.h" 60 61 #include <smldtd.h> 62 #include <smldevinfdtd.h> 63 #include <smlmetinfdtd.h> 64 #include <smldmtnddtd.h> 65 #include "mgrutil.h" 66 67 #include <libmem.h> 68 #include <libstr.h> 69 70 #include <sml.h> 71 #include <smlerr.h> 72 #include <mgr.h> 73 74 #ifdef IS_END /* to avoid redefinition of this macro */ 75 #undef IS_END 76 #endif 77 78 void 79 subdtdDecodeWbxml(XltDecoderPtr_t pDecoder,SmlPcdataPtr_t *ppPcdata); 80 81 82 /* WBXML version that this parser knows */ 83 #define _MAJOR_VERSION 1 84 #define _MINOR_VERSION 2 85 86 #define TAG_STATE 0 87 #define ATTRIBUTE_STATE 1 88 89 /* various checks about wbxml token */ 90 #define HAS_ATTRIBUTES(tag) (*tag & 0x80) 91 #define HAS_CONTENT(tag) (*tag & 0x40) 92 #define IDENTITY(tag) (*tag & 0x3F) 93 94 #define IS_SWITCH(tok) (*(tok) == 0x00) 95 #define IS_END(tok) (*(tok) == 0x01) 96 #define IS_ENTITY(tok) (*(tok) == 0x02) 97 #define IS_STR_I(tok) (*(tok) == 0x03) 98 #define IS_LITERAL(tok) (IDENTITY(tok) == 0x04) 99 // Note: gcc cannot parse multi-line macros when file has DOS line ends 100 #define IS_EXT_I(tok) ((*(tok) == 0x40) || (*(tok) == 0x41) || (*(tok) == 0x42)) 101 #define IS_PI(tok) (*(tok) == 0x43) 102 #define IS_EXT_T(tok) ((*(tok) == 0x80) || (*(tok) == 0x81) || (*(tok) == 0x82)) 103 #define IS_STR_T(tok) (*(tok) == 0x83) 104 #define IS_EXT(tok) ((*(tok) == 0xC0) || (*(tok) == 0xC1) || (*(tok) == 0xC2)) 105 #define IS_OPAQUE(tok) (*(tok) == 0xC3) 106 #define IS_STRING(tok) (IS_STR_I(tok) || IS_STR_T(tok)) 107 #define IS_EXTENSION(tok) (IS_EXT_I(tok) || IS_EXT_T(tok) || IS_EXT(tok)) 108 109 #define IS_ATTRIBUTE_VALUE(tok) (*(tok) & 0x80) 110 #define IS_ATTRIBUTE_START(tok) (~IS_ATTRIBUTE_VALUE(tok)) 111 112 113 /** 114 * Private Interface for the WBXML scanner. 115 * 116 * The private scanner interface contains some additional member attributes 117 * that are not listed in the public interface, e.g. a copy of the string 118 * table and some other items that do not need to be known outside the 119 * scanner module. 120 */ 121 typedef struct wbxmlScannerPriv_s wbxmlScannerPriv_t, *wbxmlScannerPrivPtr_t; 122 struct wbxmlScannerPriv_s 123 { 124 /* public methods */ 125 Ret_t (*nextTok)(XltDecScannerPtr_t); 126 Ret_t (*destroy)(XltDecScannerPtr_t); 127 Ret_t (*pushTok)(XltDecScannerPtr_t); 128 void (*setBuf)(XltDecScannerPtr_t pScanner, const MemPtr_t pBufStart, const MemPtr_t pBufEnd); 129 MemPtr_t (*getPos)(XltDecScannerPtr_t pScanner); 130 131 /* public attributes */ 132 XltDecTokenPtr_t curtok; /* current token */ 133 Long_t charset; /* character set as specified in the 134 WBXML header */ 135 String_t charsetStr; /* NULL */ 136 Long_t pubID; /* document public identifier as 137 specified in the WBXML header */ 138 String_t pubIDStr; /* pubID as a string - valid only when 139 pubID == 0 */ 140 Flag_t finished; /* set when end of buffer is reached */ 141 142 /* private attributes */ 143 MemPtr_t pos; /* current buffer position */ 144 MemPtr_t bufend; /* end of buffer */ 145 Long_t pubIDIdx; /* strtbl index of the string 146 version of the pubID - valid only 147 when pubID == 0 */ 148 149 XltUtilStackPtr_t tagstack; /* stack of open start tags */ 150 151 MemPtr_t strtbl; /* copy of the string table */ 152 Long_t strtbllen; /* length of the string table */ 153 154 Byte_t state; /* tag state or attribute state */ 155 SmlPcdataExtension_t cptag; /* current codepage for tags */ 156 Byte_t cpattr; /* current codepage for attributes */ 157 SmlPcdataExtension_t activeExt; /* the active Sub DTD */ 158 }; 159 160 /* typedef for multi-byte unsigned integers as specified in the 161 WAP Binary XML Content Format specification */ 162 typedef Long_t MBINT; 163 164 /** 165 * Public methods of the scanner interface. 166 * 167 * Description see XLTDecCom.h. 168 */ 169 static Ret_t _destroy(XltDecScannerPtr_t); 170 static Ret_t _nextTok(XltDecScannerPtr_t); 171 static Ret_t _pushTok(XltDecScannerPtr_t); 172 static void _setBuf(XltDecScannerPtr_t, const MemPtr_t, const MemPtr_t); 173 static MemPtr_t _getPos(XltDecScannerPtr_t); 174 175 /** 176 * FUNCTION: readBytes 177 * 178 * Advance the current position pointer after checking whether the end of 179 * the buffer has been reached. If the end of the buffer has been reached 180 * the scanner's finished flag is set. 181 182 * RETURNS: 0, if end of buffer has been reached 183 * 1 otherwise 184 */ 185 static Boolean_t readBytes(wbxmlScannerPrivPtr_t pScanner, Long_t bytes); 186 187 /** 188 * FUNCTION: parseInt 189 * 190 * Decodes multi-byte integers. 191 * 192 * PRE-Condition: 193 * pScanner->pos points to the first byte of the mb_int. 194 * 195 * POST-Condition: 196 * pScanner->pos points to the last byte of the mb_int. 197 */ 198 static Ret_t parseInt(wbxmlScannerPrivPtr_t pScanner, MBINT *mbi); 199 200 /** 201 * FUNCTION: wbxmlHeader, wbxmlVersion, wbxmlPublicID, wbxmlCharset 202 * 203 * These functions are used for decoding the WBXML document header. 204 * wbxmlHeader is a short wrapper that calls the other four functions in 205 * the right order to scan the header. wbxmlStrtbl makes a copy of the 206 * string table. 207 */ 208 static Ret_t wbxmlHeader(wbxmlScannerPrivPtr_t pScanner); 209 static Ret_t wbxmlVersion(wbxmlScannerPrivPtr_t pScanner); 210 static Ret_t wbxmlPublicID(wbxmlScannerPrivPtr_t pScanner); 211 static Ret_t wbxmlCharset(wbxmlScannerPrivPtr_t pScanner); 212 static Ret_t wbxmlStrtbl(wbxmlScannerPrivPtr_t pScanner); 213 214 /** 215 * FUNCTION: wbxmlSwitchPage 216 * 217 * Switch WBXML code page 218 */ 219 static Ret_t wbxmlSwitchPage(wbxmlScannerPrivPtr_t pScanner); 220 221 /** 222 * FUNCTION: wbxmlXXXToken 223 * 224 * Scan the document for the next valid XML/WBXML token as defined in the 225 * XLTDecCom header file (e.g. TOK_TAG_START). 226 * 227 * PRE-Condition: 228 * pScanner->pos points to the first byte of a valid WBXML 229 * element (String, Tag, etc.) 230 * 231 * POST-Condition: 232 * pScanner->pos points to the last byte of the WBXML 233 * element; 234 * pScanner->curtok contains type and tagid or pcdata of 235 * the token 236 */ 237 static Ret_t wbxmlStringToken(wbxmlScannerPrivPtr_t pScanner); 238 static Ret_t wbxmlOpaqueToken(wbxmlScannerPrivPtr_t pScanner); 239 static Ret_t wbxmlTagToken(wbxmlScannerPrivPtr_t pScanner); 240 241 /** 242 * FUNCTION: wbxmlXXXToken 243 * 244 * WBXML extensions, entities, processing instructions and attributes are 245 * not supported by this scanner. If one is found it is skipped and 246 * processing continues afterwards. 247 */ 248 static Ret_t wbxmlSkipExtension(wbxmlScannerPrivPtr_t pScanner); 249 static Ret_t wbxmlSkipEntity(wbxmlScannerPrivPtr_t pScanner); 250 static Ret_t wbxmlSkipPI(wbxmlScannerPrivPtr_t); 251 static Ret_t wbxmlSkipAttribute(wbxmlScannerPrivPtr_t); 252 253 /*************************************************************************/ 254 /* External Functions */ 255 /*************************************************************************/ 256 257 /** 258 * FUNCTION: XltDecWbxmlInit 259 * 260 * Create and initialize a new WBXML scanner. Description see XLTDec.h. 261 */ 262 Ret_t 263 xltDecWbxmlInit(const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, 264 XltDecScannerPtr_t *ppScanner) 265 { 266 wbxmlScannerPrivPtr_t pScanner; 267 Ret_t rc; 268 269 /* initialize new WBXML scanner */ 270 if ((pScanner = (wbxmlScannerPrivPtr_t)smlLibMalloc(sizeof(wbxmlScannerPriv_t))) == NULL) 271 return SML_ERR_NOT_ENOUGH_SPACE; 272 smlLibMemset(pScanner, 0, sizeof(wbxmlScannerPriv_t)); 273 pScanner->bufend = pBufEnd; 274 pScanner->pos = *ppBufPos; 275 if ((pScanner->curtok = (XltDecTokenPtr_t)smlLibMalloc(sizeof(XltDecToken_t))) == NULL) { 276 smlLibFree(pScanner); 277 *ppScanner = NULL; 278 return SML_ERR_NOT_ENOUGH_SPACE; 279 } 280 pScanner->curtok->pcdata = NULL; 281 if ((rc = xltUtilCreateStack(&pScanner->tagstack, 10)) != SML_ERR_OK) { 282 smlLibFree(pScanner->curtok); 283 smlLibFree(pScanner); 284 *ppScanner = NULL; 285 return rc; 286 } 287 pScanner->state = TAG_STATE; 288 289 /* point public/private methods to the right implementation */ 290 pScanner->nextTok = _nextTok; 291 pScanner->destroy = _destroy; 292 pScanner->pushTok = _pushTok; 293 pScanner->setBuf = _setBuf; 294 pScanner->getPos = _getPos; 295 296 /* decode WBXML header */ 297 if ((rc = wbxmlHeader(pScanner)) != SML_ERR_OK) { 298 pScanner->destroy((XltDecScannerPtr_t)pScanner); 299 *ppScanner = NULL; 300 return rc; 301 } 302 303 *ppScanner = (XltDecScannerPtr_t)pScanner; 304 305 return SML_ERR_OK; 306 } 307 308 /** 309 * FUNCTION: destroy 310 * 311 * Free memory. Description see XltDecAll.h. 312 */ 313 static Ret_t 314 _destroy(XltDecScannerPtr_t pScanner) 315 { 316 wbxmlScannerPrivPtr_t pScannerPriv; 317 318 if (pScanner == NULL) 319 return SML_ERR_OK; 320 321 pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; 322 if (pScannerPriv->tagstack != NULL) 323 pScannerPriv->tagstack->destroy(pScannerPriv->tagstack); 324 smlLibFree(pScannerPriv->curtok); 325 smlLibFree(pScannerPriv->strtbl); 326 smlLibFree(pScannerPriv); 327 328 return SML_ERR_OK; 329 } 330 331 /** 332 * FUNCTION: nextTok 333 * 334 * Get next token. 335 */ 336 static Ret_t 337 _nextTok(XltDecScannerPtr_t pScanner) 338 { 339 wbxmlScannerPrivPtr_t pScannerPriv; 340 Ret_t rc; 341 342 pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; 343 // T.K.: chanched Ptr_t to _t 344 smlLibMemset(pScanner->curtok, 0, sizeof(XltDecToken_t)); 345 pScannerPriv->curtok->start = pScannerPriv->pos; 346 347 /* keep going until we find a "supported" element */ 348 rc = SML_ERR_OK; 349 while (rc == SML_ERR_OK) { 350 /* skip PIs, extensions and entities... */ 351 if (IS_PI(pScannerPriv->pos)) { 352 rc = wbxmlSkipPI(pScannerPriv); 353 } else if (IS_EXTENSION(pScannerPriv->pos)) { 354 rc = wbxmlSkipExtension(pScannerPriv); 355 } else if (IS_ENTITY(pScannerPriv->pos)) { 356 rc = wbxmlSkipEntity(pScannerPriv); 357 358 /* ... decode strings, opaque data and tags */ 359 } else if (IS_STRING(pScannerPriv->pos)) { 360 rc = wbxmlStringToken(pScannerPriv); 361 break; 362 } else if (IS_OPAQUE(pScannerPriv->pos)) { 363 rc = wbxmlOpaqueToken(pScannerPriv); 364 break; 365 } else { 366 rc = wbxmlTagToken(pScannerPriv); 367 break; 368 } 369 } 370 371 return rc; 372 } 373 374 /** 375 * FUNCTION: pushTok 376 * 377 * Reset the scanner to the starting position of the current token within 378 * the buffer. 379 */ 380 static Ret_t 381 _pushTok(XltDecScannerPtr_t pScanner) 382 { 383 wbxmlScannerPrivPtr_t pScannerPriv; 384 XltUtilStackPtr_t pTagStack; 385 XltTagID_t tagid; 386 Ret_t rc = 0; 387 388 pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; 389 pTagStack = pScannerPriv->tagstack; 390 391 if (pScannerPriv->curtok->start == NULL) 392 return SML_ERR_WRONG_USAGE; 393 394 /* reset scanner to position where tok begins */ 395 pScannerPriv->pos = pScannerPriv->curtok->start; 396 397 /* correct the tag stack */ 398 if (pScannerPriv->curtok->type == TOK_TAG_START) { 399 rc = pTagStack->pop(pTagStack, &tagid); 400 } else if (pScannerPriv->curtok->type == TOK_TAG_END) { 401 tagid = pScannerPriv->curtok->tagid; 402 rc = pTagStack->push(pTagStack, tagid); 403 } 404 if (rc) return rc; 405 406 /* invalidate curtok */ 407 /* T.K. Possible Error. pScannerPriv->curtok is of type XltDecToken_t NOT ...Ptr_t */ 408 // OrigLine: 409 // smlLibMemset(pScannerPriv->curtok, 0, sizeof(XltDecTokenPtr_t)); 410 pScannerPriv->curtok->type = (XltTokType_t)0; 411 412 return SML_ERR_OK; 413 } 414 415 static void 416 _setBuf(XltDecScannerPtr_t pScanner, const MemPtr_t pBufStart, 417 const MemPtr_t pBufEnd) 418 { 419 wbxmlScannerPrivPtr_t pScannerPriv = (wbxmlScannerPrivPtr_t)pScanner; 420 pScannerPriv->pos = pBufStart; 421 pScannerPriv->bufend = pBufEnd; 422 } 423 424 static MemPtr_t 425 _getPos(XltDecScannerPtr_t pScanner) 426 { 427 return ((wbxmlScannerPrivPtr_t)pScanner)->pos; 428 } 429 430 /*************************************************************************/ 431 /* Internal Functions */ 432 /*************************************************************************/ 433 434 /** 435 * FUNCTION: readBytes 436 * 437 * Advance the position pointer. Description see above. 438 */ 439 static Boolean_t 440 readBytes(wbxmlScannerPrivPtr_t pScanner, Long_t bytes) 441 { 442 if (pScanner->pos + bytes > pScanner->bufend) { 443 pScanner->finished = 1; 444 return 0; 445 } 446 pScanner->pos += bytes; 447 return 1; 448 } 449 450 /** 451 * NOTICE: Entities, Extensions, Processing Instructions and Attributes 452 * are not supported by the WBXML scanner. 453 * 454 * Extensions and Attributes are document-specific and are as such not used 455 * by the SyncML specification. 456 * The scanner will just ignore and skip over them. Neither 457 * this scanner nor the parser use processing instructions so they are 458 * skipped as well. 459 */ 460 461 /** 462 * FUNCTION: wbxmlHeader 463 * 464 * Decode the WBXML header containing version number, document public 465 * identifier, character set and a string table. 466 */ 467 static Ret_t 468 wbxmlHeader(wbxmlScannerPrivPtr_t pScanner) 469 { 470 Ret_t rc; 471 472 /* decode the WBXML header */ 473 if ((rc = wbxmlVersion(pScanner)) != SML_ERR_OK) 474 return rc; 475 if ((rc = wbxmlPublicID(pScanner)) != SML_ERR_OK) 476 return rc; 477 if ((rc = wbxmlCharset(pScanner)) != SML_ERR_OK) 478 return rc; 479 if ((rc = wbxmlStrtbl(pScanner)) != SML_ERR_OK) 480 return rc; 481 return SML_ERR_OK; 482 } 483 484 /** 485 * FUNCTION: wbxmlVersion 486 * 487 * Decode WBXML version. The scanner returns an error if the major version 488 * of the document differs from the major version this scanner supports or 489 * if the minor version of the document is larger than the minor version 490 * the scanner supports. 491 */ 492 static Ret_t 493 wbxmlVersion(wbxmlScannerPrivPtr_t pScanner) 494 { 495 Byte_t major, minor; 496 497 minor = ((Byte_t)(*pScanner->pos & 0x0F)); 498 major = ((Byte_t)((*pScanner->pos >> 4) + 1)); 499 500 501 502 if (major != _MAJOR_VERSION || minor > _MINOR_VERSION) 503 return SML_ERR_XLT_INCOMP_WBXML_VERS; 504 505 if (!readBytes(pScanner, 1)) 506 return SML_ERR_XLT_END_OF_BUFFER; 507 508 return SML_ERR_OK; 509 } 510 511 /** 512 * FUNCTION: wbxmlPublicID 513 * 514 * Decodes WBXML Document Public Identifier. 515 */ 516 static Ret_t 517 wbxmlPublicID(wbxmlScannerPrivPtr_t pScanner) 518 { 519 MBINT tmp; 520 Ret_t rc; 521 522 if (*pScanner->pos != 0) { 523 /* pre-defined numeric identifier */ 524 if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK) 525 return rc; 526 pScanner->pubID = tmp; 527 pScanner->pubIDIdx = 0; 528 } else { 529 /* public id is given as string table entry (which we 530 haven't read at this point so we'll save the reference 531 for later) */ 532 if (!readBytes(pScanner, 1)) 533 return SML_ERR_XLT_END_OF_BUFFER; 534 if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK) 535 return rc; 536 pScanner->pubID = 0; 537 pScanner->pubIDIdx = tmp; 538 } 539 if (!readBytes(pScanner, 1)) 540 return SML_ERR_XLT_END_OF_BUFFER; 541 return SML_ERR_OK; 542 } 543 544 /** 545 * FUNCTION: wbxmlCharset 546 * 547 * Decode WBXML Charset. 548 */ 549 static Ret_t 550 wbxmlCharset(wbxmlScannerPrivPtr_t pScanner) 551 { 552 /* TODO: if charset iformation has to be processed 553 it can be done here. For the moment only UTF-8 is used by SyncML */ 554 MBINT mibenum; 555 Ret_t rc; 556 557 /* charset is given as a single IANA assigned MIBEnum value */ 558 if ((rc = parseInt(pScanner, &mibenum)) != SML_ERR_OK) 559 return rc; 560 pScanner->charset = mibenum; 561 562 if (!readBytes(pScanner, 1)) 563 return SML_ERR_XLT_END_OF_BUFFER; 564 565 return SML_ERR_OK; 566 } 567 568 /** 569 * FUNCTION: wbxmlStrtbl 570 * 571 * Keep a copy of the string table. 572 */ 573 static Ret_t 574 wbxmlStrtbl(wbxmlScannerPrivPtr_t pScanner) 575 { 576 MBINT len; 577 Ret_t rc; 578 579 if ((rc = parseInt(pScanner, &len)) != SML_ERR_OK) 580 return rc; 581 if (!readBytes(pScanner, 1)) 582 return SML_ERR_XLT_END_OF_BUFFER; 583 pScanner->strtbllen = len; 584 if (len > 0) { 585 if (pScanner->pos + len > pScanner->bufend) 586 return SML_ERR_XLT_END_OF_BUFFER; 587 if ((pScanner->strtbl = smlLibMalloc(len)) == NULL) 588 { 589 return SML_ERR_NOT_ENOUGH_SPACE; 590 } 591 smlLibMemcpy(pScanner->strtbl, pScanner->pos, len); 592 readBytes(pScanner, len); 593 } else { 594 pScanner->strtbl = NULL; 595 } 596 597 /* if the public ID was given as a string table reference save a 598 reference to the corresponding string for later */ 599 if (pScanner->pubID == 0) { 600 if (pScanner->pubIDIdx > pScanner->strtbllen) 601 return SML_ERR_XLT_INVAL_WBXML_DOC; 602 pScanner->pubIDStr = (String_t)(pScanner->strtbl + pScanner->pubIDIdx); 603 } 604 605 return SML_ERR_OK; 606 } 607 608 static Ret_t 609 parseInt(wbxmlScannerPrivPtr_t pScanner, MBINT *mbi) 610 { 611 *mbi = 0; 612 /* accumulate byte value until continuation flag (MSB) is zero */ 613 for (;;) { 614 *mbi = *mbi << 7; 615 *mbi += *(pScanner->pos) & 0x7F; 616 if (!(*pScanner->pos & 0x80)) break; 617 if (!readBytes(pScanner, 1)) 618 return SML_ERR_XLT_END_OF_BUFFER; 619 } 620 return SML_ERR_OK; 621 } 622 623 static Ret_t 624 wbxmlStringToken(wbxmlScannerPrivPtr_t pScanner) 625 { 626 SmlPcdataPtr_t pPcdata; 627 Ret_t rc; 628 629 if ((pPcdata = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL) 630 return SML_ERR_NOT_ENOUGH_SPACE; 631 /* copy the string into the new PCdata struct */ 632 if (IS_STR_I(pScanner->pos)) { 633 /* inline string */ 634 if (!readBytes(pScanner, 1)) 635 { 636 /* LIBnn25123 Fix*/ 637 if(pPcdata != NULL) { smlLibFree(pPcdata); pPcdata = NULL; } 638 return SML_ERR_XLT_END_OF_BUFFER; 639 } 640 pPcdata->extension = SML_EXT_UNDEFINED; 641 pPcdata->contentType = SML_PCDATA_STRING; 642 pPcdata->length = smlLibStrlen((String_t)pScanner->pos); 643 if (pScanner->pos + pPcdata->length + 1 > pScanner->bufend) { 644 smlLibFree(pPcdata); 645 return SML_ERR_XLT_END_OF_BUFFER; 646 } 647 if ((pPcdata->content = smlLibMalloc(pPcdata->length + 1)) == NULL) { 648 smlLibFree(pPcdata); 649 return SML_ERR_NOT_ENOUGH_SPACE; 650 } 651 smlLibStrncpy(pPcdata->content, (String_t)pScanner->pos, pPcdata->length + 1); 652 readBytes(pScanner, pPcdata->length + 1); 653 654 } else { 655 /* string table reference */ 656 MBINT offset; /* offset into string table */ 657 if (!readBytes(pScanner, 1)) 658 { 659 /* LIBnn25123 Fix*/ 660 if(pPcdata != NULL) { smlLibFree(pPcdata); pPcdata = NULL;} 661 return SML_ERR_XLT_END_OF_BUFFER; 662 } 663 if ((rc = parseInt(pScanner, &offset)) != SML_ERR_OK) 664 { 665 smlLibFree(pPcdata); 666 return rc; 667 } 668 if (offset >= pScanner->strtbllen) { 669 smlLibFree(pPcdata); 670 return SML_ERR_XLT_INVAL_WBXML_DOC; 671 } 672 pPcdata->contentType = SML_PCDATA_STRING; 673 pPcdata->length = smlLibStrlen((String_t)(pScanner->strtbl + offset)); 674 if ((pPcdata->content = smlLibMalloc(pPcdata->length + 1)) == NULL) { 675 smlLibFree(pPcdata); 676 return SML_ERR_NOT_ENOUGH_SPACE; 677 } 678 smlLibStrncpy(pPcdata->content, (String_t)(pScanner->strtbl + offset), pPcdata->length + 1); 679 readBytes(pScanner, 1); 680 } 681 682 pScanner->curtok->pcdata = pPcdata; 683 684 pScanner->curtok->type = TOK_CONT; 685 686 return SML_ERR_OK; 687 } 688 689 static Ret_t 690 wbxmlOpaqueToken(wbxmlScannerPrivPtr_t pScanner) 691 { 692 SmlPcdataPtr_t pPcdata = NULL; 693 MBINT len; 694 Ret_t rc; 695 696 KCDBG("wbxmlOpaqueToken: Enter\n"); 697 698 if (!readBytes(pScanner, 1)) 699 return SML_ERR_XLT_END_OF_BUFFER; 700 701 /* a mbi indicates the length of the opaque data block that we'll 702 copy into new PCdata struct */ 703 if ((rc = parseInt(pScanner, &len)) != SML_ERR_OK) 704 return rc; 705 if (!readBytes(pScanner, 1)) 706 return SML_ERR_XLT_END_OF_BUFFER; 707 if (pScanner->pos + len > pScanner->bufend) 708 return SML_ERR_XLT_END_OF_BUFFER; 709 if ((pPcdata = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL) 710 return SML_ERR_NOT_ENOUGH_SPACE; 711 pPcdata->extension = SML_EXT_UNDEFINED; 712 pPcdata->contentType = SML_PCDATA_OPAQUE; 713 pPcdata->length = len; 714 /* Modification 2001-07-03 by Luz %%%%%: 715 * made sure that content is one null byte longer 716 * than indicated opaque content, such that strings that are coded as 717 * opaque (happens to be the case with Nokia 9210) can still be read 718 * as C-string without need for an intermediate buffer 719 */ 720 /* original: 721 if ((pPcdata->content = smlLibMalloc(len)) == NULL) { 722 smlLibFree(pPcdata); 723 return SML_ERR_NOT_ENOUGH_SPACE; 724 } 725 */ 726 /* modified: */ 727 if ((pPcdata->content = smlLibMalloc(len+1)) == NULL) { 728 smlLibFree(pPcdata); 729 return SML_ERR_NOT_ENOUGH_SPACE; 730 } 731 ((char *)pPcdata->content)[len]=0; /* make sure there is a c-string terminator */ 732 /* end modification */ 733 734 smlLibMemcpy(pPcdata->content, pScanner->pos, len); 735 pScanner->curtok->pcdata = pPcdata; 736 737 readBytes(pScanner, len); 738 739 pScanner->curtok->type = TOK_CONT; 740 741 return SML_ERR_OK; 742 } 743 744 static Ret_t 745 wbxmlTagToken(wbxmlScannerPrivPtr_t pScanner) 746 { 747 XltTagID_t tagid; 748 Boolean_t has_cont, has_attr; 749 Ret_t rc; 750 751 if (IS_SWITCH(pScanner->pos)) { 752 if ((rc = wbxmlSwitchPage(pScanner)) != SML_ERR_OK) 753 return rc; 754 } 755 756 /* we have to look at the top of the tagstack to see which 757 start tag an end tag belongs to */ 758 if (IS_END(pScanner->pos)) { 759 if (!readBytes(pScanner, 1)) 760 return SML_ERR_XLT_END_OF_BUFFER; 761 pScanner->curtok->type = TOK_TAG_END; 762 rc = pScanner->tagstack->pop(pScanner->tagstack, &tagid); 763 if (rc == SML_ERR_WRONG_USAGE) 764 return SML_ERR_XLT_INVAL_WBXML_DOC; 765 else if (rc) 766 return rc; 767 pScanner->curtok->tagid = tagid; 768 return SML_ERR_OK; 769 } 770 771 772 /* look at the two MSB: does this tag have content or attributes? */ 773 774 has_cont = ((Boolean_t)(HAS_CONTENT(pScanner->pos))); 775 has_attr = ((Boolean_t)(HAS_ATTRIBUTES(pScanner->pos))); 776 777 778 /* look up tag ID either by string or by number */ 779 if (IS_LITERAL(pScanner->pos)) { 780 MBINT offset; /* offset into the string table */ 781 if (!readBytes(pScanner, 1)) 782 return SML_ERR_XLT_END_OF_BUFFER; 783 if ((rc = parseInt(pScanner, &offset)) != SML_ERR_OK) 784 return rc; 785 if (offset > pScanner->strtbllen) 786 return SML_ERR_XLT_INVAL_WBXML_DOC; 787 788 rc = (Ret_t)getTagIDByStringAndExt((String_t)(pScanner->strtbl + offset), pScanner->activeExt, &tagid); 789 if ((tagid == TN_UNDEF) || (rc != SML_ERR_OK)) return rc; 790 791 } else { 792 rc = (Ret_t)getTagIDByByteAndExt((Byte_t)IDENTITY(pScanner->pos), pScanner->activeExt, &tagid); 793 if ((tagid == TN_UNDEF) || (rc != SML_ERR_OK)) return rc; 794 795 } 796 797 /* we know everything we need to know */ 798 pScanner->curtok->tagid = tagid; 799 pScanner->curtok->type = has_cont ? TOK_TAG_START : TOK_TAG_EMPTY; 800 switch ( pScanner->cptag ) 801 { 802 case 0x00 : 803 pScanner->curtok->ext = SML_EXT_UNDEFINED; 804 break; 805 case 0x01 : 806 #ifdef __USE_METINF__ 807 pScanner->curtok->ext = SML_EXT_METINF; 808 #else 809 pScanner->curtok->ext = SML_EXT_UNDEFINED; 810 #endif 811 break; 812 case 0x02 : 813 #ifdef __USE_DMTND__ 814 pScanner->curtok->ext = SML_EXT_DMTND; 815 #else 816 pScanner->curtok->ext = SML_EXT_UNDEFINED; 817 #endif 818 break; 819 case 0xFD2 : 820 #ifdef __USE_DEVINF__ 821 pScanner->curtok->ext = SML_EXT_DEVINF; 822 #else 823 pScanner->curtok->ext = SML_EXT_UNDEFINED; 824 #endif 825 break; 826 default: 827 pScanner->curtok->ext = SML_EXT_UNDEFINED; 828 break; 829 } 830 831 if (!readBytes(pScanner, 1)) 832 return SML_ERR_XLT_END_OF_BUFFER; 833 834 /* push tag onto tagstack unless this tag is empty */ 835 if (has_cont) { 836 if ((rc = pScanner->tagstack->push(pScanner->tagstack, tagid)) != SML_ERR_OK) 837 return rc; 838 } 839 840 /* skip attributes */ 841 if (has_attr) { 842 pScanner->state = ATTRIBUTE_STATE; 843 if ((rc = wbxmlSkipAttribute(pScanner)) != SML_ERR_OK) 844 return rc; 845 pScanner->state = TAG_STATE; 846 } 847 848 return SML_ERR_OK; 849 } 850 851 /** 852 * FUNCTION: wbxmlSwitchPage 853 * 854 * Switch WBXML code page. 855 */ 856 /* T.K. 06.02.01 857 * We need to enhance this as soon as we introduce 858 * Sub DTD's with more than one WBXML codepage. But till then 859 * there is only one case where WBXML codepages can occure, and 860 * this is the MetInf Sub DTD. So in case we find a codepage switch 861 * to something other than codepage zero, we set the active extension 862 * to metinf. 863 * In future versions the pScanner needs to be enhanced, to translate 864 * codepageswitches context sensitive to the active extension. 865 */ 866 static Ret_t 867 wbxmlSwitchPage(wbxmlScannerPrivPtr_t pScanner) 868 { 869 if (!readBytes(pScanner, 1)) 870 return SML_ERR_XLT_END_OF_BUFFER; 871 if (pScanner->state == TAG_STATE) 872 pScanner->cptag = (SmlPcdataExtension_t)*pScanner->pos; 873 else 874 pScanner->cpattr = *pScanner->pos; 875 readBytes(pScanner, 1); 876 /* T.K. this needs to be adjusted as described above */ 877 /* Ken Chen/Motorola, switch WBXML switch page accordingly */ 878 879 switch ( pScanner->cptag ) 880 { 881 case 0x00 : 882 pScanner->activeExt = SML_EXT_UNDEFINED; 883 break; 884 case 0x01 : 885 #ifdef __USE_METINF__ 886 pScanner->activeExt = SML_EXT_METINF; 887 #else 888 pScanner->activeExt = SML_EXT_UNDEFINED; 889 #endif 890 break; 891 case 0x02 : 892 #ifdef __USE_DMTND__ 893 pScanner->activeExt = SML_EXT_DMTND; 894 #else 895 pScanner->activeExt = SML_EXT_UNDEFINED; 896 #endif 897 break; 898 case 0xFD2 : 899 #ifdef __USE_DEVINF__ 900 pScanner->activeExt = SML_EXT_DEVINF; 901 #else 902 pScanner->activeExt = SML_EXT_UNDEFINED; 903 #endif 904 break; 905 default: 906 pScanner->activeExt = SML_EXT_UNDEFINED; 907 break; 908 } 909 910 return SML_ERR_OK; 911 } 912 913 914 /******************************/ 915 /* Unsupported WBXML elements */ 916 /******************************/ 917 918 /** 919 * FUNCTION: wbxmlSkipEntity 920 * 921 * Skips entities but doesn't do anything useful yet. 922 */ 923 static Ret_t 924 wbxmlSkipEntity(wbxmlScannerPrivPtr_t pScanner) 925 { 926 MBINT tmp; 927 Ret_t rc; 928 929 if (!readBytes(pScanner, 1)) 930 return SML_ERR_XLT_END_OF_BUFFER; 931 if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK) 932 return rc; 933 if (!readBytes(pScanner, 1)) 934 return SML_ERR_XLT_END_OF_BUFFER; 935 936 return SML_ERR_OK; 937 } 938 939 940 /** 941 * FUNCTION: wbxmlSkipExtension 942 * 943 * Decode WBXML extensions. Skips the extension but doesn't do anything 944 * useful with it. 945 */ 946 static Ret_t 947 wbxmlSkipExtension(wbxmlScannerPrivPtr_t pScanner) 948 { 949 MBINT tmp; 950 Ret_t rc; 951 952 if (IS_EXT(pScanner->pos)) { 953 /* single byte extension token */ 954 if (!readBytes(pScanner, 1)) 955 return SML_ERR_XLT_END_OF_BUFFER; 956 } else if (IS_EXT_I(pScanner->pos)) { 957 /* inline string extension token */ 958 if (!readBytes(pScanner, 1)) 959 return SML_ERR_XLT_END_OF_BUFFER; 960 if (!readBytes(pScanner, smlLibStrlen((String_t)pScanner->pos) + 1)) 961 return SML_ERR_XLT_END_OF_BUFFER; 962 } else { 963 /* inline integer extension token */ 964 if (!readBytes(pScanner, 1)) 965 return SML_ERR_XLT_END_OF_BUFFER; 966 if ((rc = parseInt(pScanner, &tmp)) != SML_ERR_OK) 967 return rc; 968 if (!readBytes(pScanner, tmp + 1)) 969 return SML_ERR_XLT_END_OF_BUFFER; 970 } 971 return SML_ERR_OK; 972 } 973 974 /** 975 * FUNCTION: wbxmlSkipPI 976 * 977 * Handle XML processing instructions. PIs are not supported but the 978 * scanner recognizes and skips over them. 979 */ 980 static Ret_t 981 wbxmlSkipPI(wbxmlScannerPrivPtr_t pScanner) 982 { 983 /* PIs are just like tag attributes with a special PI token instead 984 * of the attribute start token */ 985 return wbxmlSkipAttribute(pScanner); 986 } 987 988 /** 989 * FUNCTION: wbxmlSkipAttribute 990 * 991 * Handle attributes. Attributes are not supported but the 992 * scanner recognizes and skips over them. 993 */ 994 static Ret_t 995 wbxmlSkipAttribute(wbxmlScannerPrivPtr_t pScanner) 996 { 997 XltDecTokenPtr_t oldtok; 998 MBINT tmp; 999 Ret_t rc = 0; 1000 1001 /* skipping attributes shouldn't change the current token so we 1002 make a copy... */ 1003 if ((oldtok = (XltDecTokenPtr_t)smlLibMalloc(sizeof(XltDecToken_t))) == NULL) 1004 return SML_ERR_NOT_ENOUGH_SPACE; 1005 smlLibMemcpy(oldtok, pScanner->curtok, sizeof(XltDecToken_t)); 1006 1007 /* ... skip until attribute end tag... */ 1008 while (!IS_END(pScanner->pos)) { 1009 if (IS_STRING(pScanner->pos)) { 1010 rc = wbxmlStringToken(pScanner); 1011 /* avoid memory leak due to this ugly workaround of 1012 skipping attributes */ 1013 smlLibFree(pScanner->curtok->pcdata); 1014 } else if (IS_EXTENSION(pScanner->pos)) { 1015 rc = wbxmlSkipExtension(pScanner); 1016 } else if (IS_ENTITY(pScanner->pos)) { 1017 rc = wbxmlSkipEntity(pScanner); 1018 } else if (IS_OPAQUE(pScanner->pos)) { 1019 rc = wbxmlOpaqueToken(pScanner); 1020 /* avoid memory leak due to this ugly workaround of 1021 skipping attributes */ 1022 smlLibFree(pScanner->curtok->pcdata); 1023 } else if (IS_LITERAL(pScanner->pos)) { 1024 if (!readBytes(pScanner, 1)) 1025 { 1026 if(oldtok) { smlLibFree(oldtok); oldtok= NULL; } 1027 return SML_ERR_XLT_END_OF_BUFFER; 1028 } 1029 rc = parseInt(pScanner, &tmp); 1030 if (!readBytes(pScanner, 1)) 1031 { 1032 if(oldtok) { smlLibFree(oldtok); oldtok= NULL; } 1033 return SML_ERR_XLT_END_OF_BUFFER; 1034 } 1035 } else if (IS_SWITCH(pScanner->pos)) { 1036 rc = wbxmlSwitchPage(pScanner); 1037 } else { 1038 if (!readBytes(pScanner, 1)) 1039 { 1040 if(oldtok) { smlLibFree(oldtok); oldtok= NULL; } 1041 return SML_ERR_XLT_END_OF_BUFFER; 1042 } 1043 } 1044 1045 if (rc != SML_ERR_OK) { 1046 smlLibFree(oldtok); 1047 return rc; 1048 } 1049 1050 } 1051 /* ... then skip the end tag itself... */ 1052 readBytes(pScanner, 1); 1053 1054 /* ... and finaly restore our copy of curtok */ 1055 smlLibMemcpy(pScanner->curtok, oldtok, sizeof(XltDecToken_t)); 1056 smlLibFree(oldtok); 1057 1058 return SML_ERR_OK; 1059 } 1060 1061 #ifdef __USE_EXTENSIONS__ 1062 /* 1063 * This function tries to decode an inlined WBXML document inside 1064 * an PCDATA element. 1065 * In case of failing to decode it the PCDATA element isn't changed 1066 * at all. 1067 */ 1068 1069 void 1070 subdtdDecodeWbxml(XltDecoderPtr_t pDecoder,SmlPcdataPtr_t *ppPcdata) { 1071 Ret_t _err = SML_ERR_OK; 1072 MemPtr_t pSubBuf = NULL; 1073 SmlPcdataPtr_t pSubPcdata = NULL; 1074 XltDecoderPtr_t pSubDecoder = NULL; 1075 SmlPcdataExtension_t ext = 0; 1076 #ifdef __USE_DEVINF__ 1077 wbxmlScannerPrivPtr_t pScannerPriv = NULL; 1078 #endif 1079 1080 KCDBG("subdtdDecodeWbxml: Enter\n"); 1081 1082 /* some sanity checks at first */ 1083 1084 if (*ppPcdata == NULL) { 1085 if (pDecoder) /* use this rare case to remove warning */ 1086 { 1087 } 1088 return; 1089 } 1090 1091 if ((*ppPcdata)->contentType != SML_PCDATA_OPAQUE) return; 1092 1093 // now create a sub buffer 1094 pSubBuf = (MemPtr_t)smlLibMalloc((*ppPcdata)->length); 1095 if (pSubBuf == NULL) return; 1096 smlLibMemset(pSubBuf, 0x00, (*ppPcdata)->length); 1097 smlLibMemmove(pSubBuf, (*ppPcdata)->content, (*ppPcdata)->length); 1098 1099 /* ok looks fine sofar - now lets decode the rest */ 1100 /* now lets create a decoder, but without parsing the SyncML 1101 * start tags (because it's not there) and skip the XML 1102 * part as we don't need it. 1103 */ 1104 pSubDecoder = (XltDecoderPtr_t)smlLibMalloc(sizeof(XltDecoder_t)); 1105 if (pSubDecoder == NULL) { 1106 smlLibFree(pSubBuf); 1107 return; 1108 } 1109 1110 KCDBG("subdtdDecodeWbxml: allocated decoder\n"); 1111 1112 pSubDecoder->finished = 0; 1113 pSubDecoder->final = 0; 1114 pSubDecoder->scanner = NULL; 1115 if (xltUtilCreateStack(&pSubDecoder->tagstack, 10) != SML_ERR_OK) { 1116 xltDecTerminate(pSubDecoder); 1117 smlLibFree(pSubBuf); 1118 return; 1119 } 1120 if (xltDecWbxmlInit(pSubBuf+(*ppPcdata)->length,&pSubBuf, &pSubDecoder->scanner) != SML_ERR_OK) { 1121 xltDecTerminate(pSubDecoder); 1122 smlLibFree(pSubBuf); 1123 return; 1124 } 1125 pSubDecoder->charset = pSubDecoder->scanner->charset; 1126 pSubDecoder->charsetStr = NULL; 1127 1128 pSubPcdata = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t)); 1129 if (pSubPcdata == NULL) { 1130 xltDecTerminate(pSubDecoder); 1131 smlLibFree(pSubPcdata); 1132 smlLibFree(pSubBuf); 1133 return; 1134 } 1135 smlLibMemset(pSubPcdata, 0, sizeof(SmlPcdata_t)); 1136 1137 _err = SML_ERR_UNSPECIFIC; 1138 1139 // detect document type and parse 1140 pScannerPriv = (wbxmlScannerPrivPtr_t)pSubDecoder->scanner; 1141 pScannerPriv->activeExt = 0; 1142 pScannerPriv->cpattr = 0; 1143 pScannerPriv->cptag = (SmlPcdataExtension_t)0; 1144 smlLibMemset(pScannerPriv->curtok, 0,sizeof(XltDecToken_t)); 1145 1146 if (((_err = nextToken(pSubDecoder)) == SML_ERR_OK)) { 1147 1148 if (IS_START(pSubDecoder->scanner->curtok)) { 1149 ext = pSubDecoder->scanner->curtok->ext; 1150 if ((_err = discardToken(pSubDecoder)) == SML_ERR_OK) { 1151 1152 pSubPcdata->contentType = SML_PCDATA_EXTENSION; 1153 pSubPcdata->extension = ext; 1154 1155 pScannerPriv->activeExt = ext; 1156 1157 switch (ext) { 1158 #ifdef __USE_DEVINF__ 1159 case SML_EXT_DEVINF: 1160 KCDBG("subdtdDecodeWbxml: EXT_DEVINF detected\n"); 1161 _err = buildDevInfDevInfCmd(pSubDecoder, (VoidPtr_t)&pSubPcdata->content); 1162 break; 1163 #endif 1164 #ifdef __USE_DMTND__ 1165 case SML_EXT_DMTND: 1166 KCDBG("subdtdDecodeWbxml: EXT_DMTND detected\n"); 1167 _err = buildDmTndCmd(pSubDecoder, (VoidPtr_t)&pSubPcdata->content); 1168 break; 1169 #endif 1170 default: 1171 KCDBG("subdtdDecodeWbxml: unknown extension detected\n"); 1172 _err = SML_ERR_XLT_INVAL_EXT; 1173 break; 1174 } 1175 } 1176 1177 } 1178 1179 } 1180 1181 if (_err != SML_ERR_OK) { 1182 KCDBG("subdtdDecodeWbxml: failed to parse\n"); 1183 xltDecTerminate(pSubDecoder); 1184 smlLibFree(pSubPcdata); 1185 smlLibFree(pSubBuf); 1186 return; 1187 } 1188 1189 /* parsing is done, now lets anchor it within the original PCDATA element */ 1190 smlFreePcdata(*ppPcdata); 1191 *ppPcdata = pSubPcdata; 1192 1193 /* we are done */ 1194 xltDecTerminate(pSubDecoder); 1195 smlLibFree(pSubBuf); 1196 1197 KCDBG("subdtdDecodeWbxml: Leave\n"); 1198 1199 return; 1200 } 1201 1202 #endif 1203 1204 /*Added by w21034 begin*/ 1205 Ret_t wbxml2xmlInternal(unsigned char *bufIn, int bufInLen, unsigned char *bufOut, int * bufOutLen) 1206 { 1207 #define Debug printf 1208 Debug("Enter wbxml2xmlInternal\n"); 1209 wbxmlScannerPrivPtr_t pScanner; 1210 Ret_t rc; 1211 1212 //check 1213 int smlInitByMe = 0; 1214 if(mgrGetSyncMLAnchor()== NULL) 1215 { 1216 Debug("Init syncML\n"); 1217 SmlOptions_t smlOptions; 1218 memset(&smlOptions, 0, sizeof(smlOptions)); 1219 smlOptions.defaultPrintFunc = NULL; 1220 smlOptions.maxWorkspaceAvailMem = 40000; 1221 rc = smlInit(&smlOptions); 1222 if(rc!=SML_ERR_OK) 1223 { 1224 return rc; 1225 } 1226 smlInitByMe = 1; 1227 } 1228 1229 /* initialize new WBXML scanner */ 1230 if ((pScanner = (wbxmlScannerPrivPtr_t)smlLibMalloc(sizeof(wbxmlScannerPriv_t))) == NULL) 1231 { 1232 if(smlInitByMe == 1) 1233 { 1234 smlTerminate(); 1235 } 1236 return SML_ERR_NOT_ENOUGH_SPACE; 1237 } 1238 smlLibMemset(pScanner, 0, sizeof(wbxmlScannerPriv_t)); 1239 //Debug("wbxml2xmlInternal 2\n"); 1240 pScanner->bufend = bufIn + bufInLen; 1241 pScanner->pos = bufIn; 1242 if ((pScanner->curtok = (XltDecTokenPtr_t)smlLibMalloc(sizeof(XltDecToken_t))) == NULL) { 1243 smlLibFree(pScanner); 1244 pScanner = NULL; 1245 if(smlInitByMe == 1) 1246 { 1247 smlTerminate(); 1248 } 1249 return SML_ERR_NOT_ENOUGH_SPACE; 1250 } 1251 //Debug("wbxml2xmlInternal 3\n"); 1252 pScanner->curtok->pcdata = NULL; 1253 if ((rc = xltUtilCreateStack(&pScanner->tagstack, 10)) != SML_ERR_OK) { 1254 smlLibFree(pScanner->curtok); 1255 smlLibFree(pScanner); 1256 if(smlInitByMe == 1) 1257 { 1258 smlTerminate(); 1259 } 1260 return rc; 1261 } 1262 pScanner->state = TAG_STATE; 1263 1264 //Debug("wbxml2xmlInternal 4\n"); 1265 /* point public/private methods to the right implementation */ 1266 pScanner->nextTok = _nextTok; 1267 pScanner->destroy = _destroy; 1268 pScanner->pushTok = _pushTok; 1269 pScanner->setBuf = _setBuf; 1270 pScanner->getPos = _getPos; 1271 1272 //Debug("wbxml2xmlInternal 5\n"); 1273 unsigned char* tmpBufOut = bufOut; 1274 int tmpBufOutLen = 0; 1275 1276 Debug("wbxml2xmlInternal 6\n"); 1277 /* decode the WBXML header */ 1278 /*decode wbxml verson*/ 1279 Byte_t major, minor; 1280 minor = ((Byte_t)(*pScanner->pos & 0x0F)); 1281 major = ((Byte_t)((*pScanner->pos >> 4) + 1)); 1282 String_t wbxmlVer = NULL; 1283 if((wbxmlVer = smlLibMalloc(50))== NULL) 1284 { 1285 pScanner->destroy((XltDecScannerPtr_t)pScanner); 1286 if(smlInitByMe == 1) 1287 { 1288 smlTerminate(); 1289 } 1290 return SML_ERR_NOT_ENOUGH_SPACE; 1291 } 1292 Debug("wbxml2xmlInternal 7\n"); 1293 smlLibMemset(wbxmlVer, 0, 50); 1294 sprintf(wbxmlVer, "<WBXML Version=%d.%d/>", (int)major, (int)minor); 1295 tmpBufOutLen = smlLibStrlen(wbxmlVer); 1296 smlLibStrncpy((String_t)tmpBufOut, (String_t)wbxmlVer, tmpBufOutLen); 1297 tmpBufOut += tmpBufOutLen; 1298 Debug("wbxml2xmlInternal 7.1,%s\n", wbxmlVer); 1299 smlLibFree(wbxmlVer); 1300 tmpBufOut[0] = '\n'; 1301 tmpBufOut++; 1302 tmpBufOut[0] = '\0'; 1303 //Debug("wbxml2xmlInternal 8\n"); 1304 if (!readBytes(pScanner, 1)) 1305 { 1306 pScanner->destroy((XltDecScannerPtr_t)pScanner); 1307 if(smlInitByMe == 1) 1308 { 1309 smlTerminate(); 1310 } 1311 return SML_ERR_XLT_END_OF_BUFFER; 1312 } 1313 1314 Debug("wbxml2xmlInternal 9\n"); 1315 /*decode public ID*/ 1316 if ((rc = wbxmlPublicID(pScanner)) != SML_ERR_OK) 1317 { 1318 pScanner->destroy((XltDecScannerPtr_t)pScanner); 1319 if(smlInitByMe == 1) 1320 { 1321 smlTerminate(); 1322 } 1323 return rc; 1324 } 1325 /*decode charset*/ 1326 if ((rc = wbxmlCharset(pScanner)) != SML_ERR_OK) 1327 { 1328 pScanner->destroy((XltDecScannerPtr_t)pScanner); 1329 if(smlInitByMe == 1) 1330 { 1331 smlTerminate(); 1332 } 1333 return rc; 1334 } 1335 /*decode string table*/ 1336 if ((rc = wbxmlStrtbl(pScanner)) != SML_ERR_OK) 1337 { 1338 pScanner->destroy((XltDecScannerPtr_t)pScanner); 1339 if(smlInitByMe == 1) 1340 { 1341 smlTerminate(); 1342 } 1343 return rc; 1344 } 1345 1346 //Debug("wbxml2xmlInternal 10\n"); 1347 smlLibMemset(pScanner->curtok, 0, sizeof(XltDecToken_t)); 1348 pScanner->curtok->start = pScanner->pos; 1349 String_t tmpStr = smlLibMalloc(50); 1350 if(tmpStr == NULL) 1351 { 1352 pScanner->destroy((XltDecScannerPtr_t)pScanner); 1353 if(smlInitByMe == 1) 1354 { 1355 smlTerminate(); 1356 } 1357 return SML_ERR_XLT_END_OF_BUFFER; 1358 } 1359 //Debug("wbxml2xmlInternal 11\n"); 1360 smlLibMemset(tmpStr, 0, 50); 1361 char startBracket[2]; 1362 startBracket[0] = '\<'; 1363 startBracket[1] = '\0'; 1364 char endBracket[2]; 1365 endBracket[0]='\>'; 1366 endBracket[1]='\0'; 1367 char forwardSlash[2]; 1368 forwardSlash[0] = '\/'; 1369 forwardSlash[1] = '\0'; 1370 1371 Debug("wbxml2xmlInternal 12\n"); 1372 smlLibMemset(pScanner->curtok, 0, sizeof(XltDecToken_t)); 1373 pScanner->curtok->start = pScanner->pos; 1374 int tagStartFlag = 0; 1375 /* keep going until we find a "supported" element */ 1376 rc = SML_ERR_OK; 1377 while (rc == SML_ERR_OK) { 1378 /* skip PIs, extensions and entities... */ 1379 if (IS_PI(pScanner->pos)) { 1380 //Debug("wbxml2xmlInternal 13, PI\n"); 1381 rc = wbxmlSkipPI(pScanner); 1382 //Debug("wbxml2xmlInternal 13, PI end\n"); 1383 } else if (IS_EXTENSION(pScanner->pos)) { 1384 //Debug("wbxml2xmlInternal 14, Extension\n"); 1385 rc = wbxmlSkipExtension(pScanner); 1386 //Debug("wbxml2xmlInternal 14, Extension End\n"); 1387 } else if (IS_ENTITY(pScanner->pos)) { 1388 //Debug("wbxml2xmlInternal 15, ENTITY\n"); 1389 rc = wbxmlSkipEntity(pScanner); 1390 //Debug("wbxml2xmlInternal 15, ENTITY End\n"); 1391 1392 /* ... decode strings, opaque data and tags */ 1393 } else if (IS_STRING(pScanner->pos)) { 1394 //Debug("wbxml2xmlInternal 16, STRING\n"); 1395 rc = wbxmlStringToken(pScanner); 1396 if(rc == SML_ERR_OK) 1397 { 1398 SmlPcdataPtr_t pcdata = pScanner->curtok->pcdata; 1399 smlLibMemcpy(tmpBufOut, pcdata->content, pcdata->length); 1400 tmpBufOut+=pcdata->length; 1401 } 1402 smlLibMemset(pScanner->curtok, 0, sizeof(XltDecToken_t)); 1403 pScanner->curtok->start = pScanner->pos; 1404 //Debug("wbxml2xmlInternal 16, STRING end\n"); 1405 } else if (IS_OPAQUE(pScanner->pos)) { 1406 //Debug("wbxml2xmlInternal 17, OPAQUE\n"); 1407 rc = wbxmlOpaqueToken(pScanner); 1408 if(rc == SML_ERR_OK) 1409 { 1410 SmlPcdataPtr_t pcdata = pScanner->curtok->pcdata; 1411 smlLibMemcpy(tmpBufOut, pcdata->content, pcdata->length); 1412 tmpBufOut+=pcdata->length; 1413 } 1414 smlLibMemset(pScanner->curtok, 0, sizeof(XltDecToken_t)); 1415 pScanner->curtok->start = pScanner->pos; 1416 //Debug("wbxml2xmlInternal 17, OPAQUE End\n"); 1417 //break; 1418 } else { 1419 Debug("wbxml2xmlInternal 18, TAG\n"); 1420 rc = wbxmlTagToken(pScanner); 1421 if(rc != SML_ERR_OK) 1422 { 1423 break; 1424 } 1425 //Debug("wbxml2xmlInternal 18.1, TAG\n"); 1426 //Generate string for the token. 1427 String_t _tagString = smlLibMalloc(50); 1428 if (_tagString == NULL) 1429 { 1430 //Debug("wbxml2xmlInternal 18.1.1, TAG\n"); 1431 smlLibFree(tmpStr); 1432 pScanner->destroy((XltDecScannerPtr_t)pScanner); 1433 //Debug("wbxml2xmlInternal 18.1.2, TAG\n"); 1434 if(smlInitByMe == 1) 1435 { 1436 smlTerminate(); 1437 } 1438 return SML_ERR_NOT_ENOUGH_SPACE; 1439 } 1440 smlLibMemset(_tagString, 0, 50); 1441 Debug("wbxml2xmlInternal 18.2, TAG\n"); 1442 //Debug("tagid=%d, ext=%d\n",pScanner->curtok->tagid, pScanner->curtok->ext); 1443 if ((rc = getTagString(pScanner->curtok->tagid, _tagString, pScanner->activeExt)) != SML_ERR_OK) 1444 { 1445 if(pScanner->curtok->type == TOK_TAG_END) 1446 { 1447 SmlPcdataExtension_t tmpExt = SML_EXT_UNDEFINED; 1448 if(tmpExt == pScanner->activeExt) 1449 { 1450 tmpExt = SML_EXT_METINF; 1451 } 1452 smlLibMemset(_tagString, 0, 50); 1453 rc =getTagString(pScanner->curtok->tagid, _tagString, tmpExt); 1454 } 1455 if(rc != SML_ERR_OK) 1456 { 1457 Debug("wbxml2xmlInternal 18.2.1, TAG, rc=%d\n", rc); 1458 smlLibFree(_tagString); 1459 break; 1460 } 1461 } 1462 smlLibMemset(tmpStr, 0, 50); 1463 if(pScanner->curtok->type == TOK_TAG_START) 1464 { 1465 Debug("wbxml2xmlInternal 18.6, TAG\n"); 1466 if(tagStartFlag == 1) 1467 { 1468 sprintf(tmpStr, "\n%s%s%s", startBracket, _tagString, endBracket); 1469 } 1470 else 1471 { 1472 sprintf(tmpStr, "%s%s%s", startBracket, _tagString, endBracket); 1473 } 1474 smlLibStrcpy((String_t)tmpBufOut, tmpStr); 1475 tmpBufOut += smlLibStrlen(tmpStr); 1476 tagStartFlag = 1; 1477 } 1478 else if(pScanner->curtok->type == TOK_TAG_END) 1479 { 1480 Debug("wbxml2xmlInternal 18.7, TAG\n"); 1481 sprintf(tmpStr, "%s%s%s%s\n", startBracket, forwardSlash, _tagString, endBracket); 1482 Debug("tmpStr=%s\n", tmpStr); 1483 smlLibStrcpy((String_t)tmpBufOut, tmpStr); 1484 tmpBufOut += smlLibStrlen(tmpStr); 1485 tagStartFlag = 0; 1486 } 1487 else if(pScanner->curtok->type == TOK_TAG_EMPTY) 1488 { 1489 } 1490 smlLibFree(_tagString); 1491 smlLibMemset(pScanner->curtok, 0, sizeof(XltDecToken_t)); 1492 pScanner->curtok->start = pScanner->pos; 1493 //break; 1494 } 1495 } 1496 if(smlInitByMe == 1) 1497 { 1498 smlTerminate(); 1499 } 1500 //Debug("wbxml2xmlInternal 20\n"); 1501 tmpBufOut[0]='\0'; 1502 *bufOutLen = (int)tmpBufOut - (int)bufOut; 1503 smlLibFree(tmpStr); 1504 pScanner->destroy((XltDecScannerPtr_t)pScanner); 1505 //Debug("Output buffer is: \n%s\n", (char*)bufOut); 1506 Debug("wbxml2xmlInternal 21, bufOutLen=%d\n", *bufOutLen); 1507 if(rc == SML_ERR_XLT_END_OF_BUFFER) 1508 { 1509 rc = SML_ERR_OK; 1510 } 1511 return rc; 1512 } 1513 /*Added by w21034 end*/ 1514 1515 1516 #endif 1517