Home | History | Annotate | Download | only in src
      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