Home | History | Annotate | Download | only in src
      1 /*************************************************************************/
      2 /* module:         SyncmML Decoder                                       */
      3 /* file:           XLTDec.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 SyncML parser.
     46  */
     47 
     48 /*************************************************************************/
     49 /* Definitions                                                           */
     50 /*************************************************************************/
     51 #include "xltdec.h"
     52 #include "xltdeccom.h"
     53 #include "xlttags.h"
     54 #include "xltutilstack.h"
     55 #include "xlttagtbl.h"
     56 #include "xltmetinf.h"
     57 #include "xltdevinf.h"
     58 #include "xltdmtnd.h"
     59 
     60 #include <smldef.h>
     61 #include <smldtd.h>
     62 #include <smlmetinfdtd.h>
     63 #include <smldevinfdtd.h>
     64 #include <smldmtnddtd.h>
     65 #include <smlerr.h>
     66 
     67 #include <libmem.h>
     68 #include <libstr.h>
     69 #include <mgrutil.h>
     70 
     71 #ifdef __USE_EXTENSIONS__
     72 /* prototype for function in xltdecwbxml.c */
     73 void subdtdDecodeWbxml(XltDecoderPtr_t pDecoder,SmlPcdataPtr_t *ppPcdata);
     74 #endif
     75 
     76 /**
     77  * FUNCTION: concatPCData
     78  *
     79  * Tries to concatenate two Pcdata elements. Only works when the two
     80  * elements are of the same type (e.g. SML_PCDATA_STRING). Returns a
     81  * pointer to the new Pcdata element or NULL if concatenation failed.
     82  */
     83 static SmlPcdataPtr_t concatPCData(SmlPcdataPtr_t pDat1, const SmlPcdataPtr_t pDat2);
     84 
     85 
     86 /**
     87  * FUNCTION: appendXXXList
     88  *
     89  * These are auxiliary functions for building SyncML elements that contain
     90  * lists of certain other data structures (e.g. Items). They take an
     91  * existing list (e.g. of type ItemListPtr_t) and append an appropriate
     92  * element at the end. If the ListPtr points to NULL a new list is created.
     93  *
     94  * PRE-Condition:
     95  *                 The scanner's current token is the start tag (may be
     96  *                 empty) of the SyncML element to be appended to the list.
     97  *
     98  * POST-Condition:
     99  *                 The scanner's current token is the end tag (or empty
    100  *                 start tag) of the SyncML element that was added to the
    101  *                 list.
    102  *
    103  * IN/OUT:         pDecoder, the decoder
    104  *                 ppXXXList, NULL or an initialized list, to which element
    105  *                 will be appended
    106  *
    107  * RETURNS:        SML_ERR_OK, if an element was successfully appended
    108  *                 else error code
    109  */
    110 static Ret_t appendItemList(XltDecoderPtr_t pDecoder, SmlItemListPtr_t *ppItemList);
    111 static Ret_t appendSourceList(XltDecoderPtr_t pDecoder, SmlSourceListPtr_t *ppSourceList);
    112 #ifdef MAPITEM_RECEIVE
    113   static Ret_t appendMapItemList(XltDecoderPtr_t pDecoder, SmlMapItemListPtr_t *ppMapItemList);
    114 #endif
    115 static Ret_t appendTargetRefList(XltDecoderPtr_t pDecoder, SmlTargetRefListPtr_t *ppTargetRefList);
    116 static Ret_t appendSourceRefList(XltDecoderPtr_t pDecoder, SmlSourceRefListPtr_t *ppSourceRefList);
    117 
    118 /* if the commands are not defined we let the functions point to NULL */
    119 #ifndef RESULT_RECEIVE
    120 #define buildResults NULL
    121 #endif
    122 
    123 #ifndef MAP_RECEIVE
    124 #define buildMap NULL
    125 #endif
    126 
    127 #ifndef EXEC_RECEIVE
    128 #define buildExec NULL
    129 #endif
    130 
    131 #if !defined(ATOM_RECEIVE) && !defined(SEQUENCE_RECEIVE)
    132 #define buildAtomOrSeq NULL
    133 #endif
    134 
    135 #ifndef SEARCH_RECEIVE
    136 #define buildSearch NULL
    137 #endif
    138 
    139 
    140 typedef struct PEBuilder_s
    141 {
    142     XltTagID_t     tagid;
    143     SmlProtoElement_t type;
    144     Ret_t (*build)(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem);
    145 } PEBuilder_t, *PEBuilderPtr_t;
    146 
    147 PEBuilderPtr_t getPETable(void);
    148 
    149 PEBuilderPtr_t getPETable(void)
    150 {
    151   PEBuilderPtr_t _tmpPEPtr;
    152   PEBuilder_t PE[] = {
    153     { TN_ADD,       SML_PE_ADD,             buildGenericCmd },
    154     { TN_ALERT,     SML_PE_ALERT,           buildAlert      },
    155     { TN_ATOMIC,    SML_PE_ATOMIC_START,    buildAtomOrSeq  },
    156     { TN_COPY,      SML_PE_COPY,            buildGenericCmd },
    157     { TN_DELETE,    SML_PE_DELETE,          buildGenericCmd },
    158     { TN_EXEC,      SML_PE_EXEC,            buildExec       },
    159     { TN_GET,       SML_PE_GET,             buildPutOrGet   },
    160     { TN_MAP,       SML_PE_MAP,             buildMap        },
    161     { TN_PUT,       SML_PE_PUT,             buildPutOrGet   },
    162     { TN_RESULTS,   SML_PE_RESULTS,         buildResults    },
    163     { TN_SEARCH,    SML_PE_SEARCH,          buildSearch     },
    164     { TN_SEQUENCE,  SML_PE_SEQUENCE_START,  buildAtomOrSeq  },
    165     { TN_STATUS,    SML_PE_STATUS,          buildStatus     },
    166     { TN_SYNC,      SML_PE_SYNC_START,      buildSync       },
    167     { TN_REPLACE,   SML_PE_REPLACE,         buildGenericCmd },
    168     { TN_UNDEF,     SML_PE_UNDEF,           0               }
    169   };
    170 
    171   _tmpPEPtr = smlLibMalloc(sizeof(PE));
    172   if (_tmpPEPtr == NULL) return NULL;
    173   smlLibMemcpy(_tmpPEPtr, &PE, sizeof(PE));
    174   return _tmpPEPtr;
    175 }
    176 
    177 /*************************************************************************/
    178 /* External Functions                                                    */
    179 /*************************************************************************/
    180 /**
    181  * Description see XLTDec.h header file.
    182  */
    183 Ret_t
    184 xltDecInit(const SmlEncoding_t enc,
    185         const MemPtr_t pBufEnd,
    186         MemPtr_t *ppBufPos,
    187         XltDecoderPtr_t *ppDecoder,
    188         SmlSyncHdrPtr_t *ppSyncHdr)
    189 {
    190     XltDecoderPtr_t pDecoder;
    191     Ret_t rc;
    192 
    193 
    194     /* create new decoder object */
    195     if ((pDecoder = (XltDecoderPtr_t)smlLibMalloc(sizeof(XltDecoder_t))) == NULL)
    196         return SML_ERR_NOT_ENOUGH_SPACE;
    197     pDecoder->finished = 0;
    198     pDecoder->final = 0;
    199     pDecoder->scanner = NULL;
    200     if ((rc = xltUtilCreateStack(&pDecoder->tagstack, 10)) != SML_ERR_OK) {
    201         xltDecTerminate(pDecoder);
    202         return rc;
    203     }
    204 
    205 #ifdef __SML_WBXML__
    206     if (enc == SML_WBXML)
    207     {
    208         rc = xltDecWbxmlInit(pBufEnd, ppBufPos, &pDecoder->scanner);
    209         if (rc == SML_ERR_OK)
    210         {
    211             pDecoder->charset = pDecoder->scanner->charset;
    212             pDecoder->charsetStr = NULL;
    213         }
    214     } else
    215 #endif
    216 
    217 #ifdef __SML_XML__
    218     if (enc == SML_XML)
    219     {
    220 
    221         rc = xltDecXmlInit(pBufEnd, ppBufPos, &pDecoder->scanner);
    222         if (rc == SML_ERR_OK)
    223         {
    224             pDecoder->charset = 0;
    225             pDecoder->charsetStr = pDecoder->scanner->charsetStr;
    226         }
    227     } else
    228 #endif
    229 
    230     {
    231         rc = SML_ERR_XLT_ENC_UNK;
    232     }
    233 
    234     if (rc != SML_ERR_OK)
    235     {
    236         xltDecTerminate((XltDecoderPtr_t)pDecoder);
    237         return rc;
    238     }
    239 
    240     /* try to find SyncHdr element, first comes the SyncML tag... */
    241     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
    242         xltDecTerminate((XltDecoderPtr_t)pDecoder);
    243         return rc;
    244     }
    245     if (!IS_START(pDecoder->scanner->curtok) ||
    246             (pDecoder->scanner->curtok->tagid != TN_SYNCML)) {
    247         smlFreePcdata(pDecoder->scanner->curtok->pcdata);
    248         xltDecTerminate((XltDecoderPtr_t)pDecoder);
    249         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    250     }
    251 
    252     /* ... then the SyncHdr */
    253     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
    254         xltDecTerminate((XltDecoderPtr_t)pDecoder);
    255         return rc;
    256     }
    257     if ((rc = buildSyncHdr(pDecoder, (VoidPtr_t)ppSyncHdr)) != SML_ERR_OK) {
    258         xltDecTerminate((XltDecoderPtr_t)pDecoder);
    259         return rc;
    260     }
    261 
    262     *ppBufPos = pDecoder->scanner->getPos(pDecoder->scanner);
    263 
    264 #ifdef __DM_TND__
    265     pDecoder->smlEncoding = enc;
    266     pDecoder->tndsEncoding = pDecoder->smlEncoding;
    267 #endif
    268     *ppDecoder = (XltDecoderPtr_t)pDecoder;
    269 
    270     return SML_ERR_OK;
    271 }
    272 
    273 /**
    274  * Description see XLTDec.h header file.
    275  */
    276 Ret_t
    277 xltDecNext(XltDecoderPtr_t pDecoder,
    278         const MemPtr_t pBufEnd,
    279         MemPtr_t *ppBufPos,
    280         SmlProtoElement_t *pe,
    281         VoidPtr_t *ppContent)
    282 {
    283     XltDecoderPtr_t pDecPriv = (XltDecoderPtr_t)pDecoder;
    284     XltDecScannerPtr_t pScanner = pDecPriv->scanner;
    285     XltTagID_t tagid;
    286     Ret_t rc;
    287     int i;
    288 
    289     pScanner->setBuf(pScanner, *ppBufPos, pBufEnd);
    290 
    291     /* if we are still outside the SyncBody, look for SyncBody start tag */
    292     if ((rc = pDecPriv->tagstack->top(pDecPriv->tagstack, &tagid)) != SML_ERR_OK)
    293         return rc;
    294     if (tagid == TN_SYNCML) {
    295         if (((rc = nextToken(pDecPriv)) != SML_ERR_OK)) {
    296             return rc;
    297         }
    298         if (!((IS_START(pScanner->curtok)) &&
    299              (pScanner->curtok->tagid == TN_SYNCBODY))) {
    300             return SML_ERR_XLT_INVAL_PROTO_ELEM;
    301         }
    302     }
    303 
    304     if ((rc = nextToken(pDecPriv)) != SML_ERR_OK)
    305         return rc;
    306 
    307     /* if we find a SyncML protocol element build the corresponding
    308        data structure */
    309     if ((IS_START_OR_EMPTY(pScanner->curtok)) && (pScanner->curtok->tagid != TN_FINAL)) {
    310 
    311         PEBuilderPtr_t pPEs = getPETable();
    312         if (pPEs == NULL)
    313         {
    314           smlLibFree(pPEs);
    315           return SML_ERR_NOT_ENOUGH_SPACE;
    316         }
    317         i = 0;
    318         while (((pPEs+i)->tagid) != TN_UNDEF)
    319         {
    320             if (((pPEs+i)->tagid) == pScanner->curtok->tagid)
    321             {
    322                 *pe = ((pPEs+i)->type);
    323                 if ((rc = (pPEs+i)->build(pDecPriv, ppContent)) != SML_ERR_OK)
    324                 {
    325                     smlLibFree(pPEs);
    326                     return rc;
    327                 }
    328                 /* T.K. adjust the SML_PE_ for 'generic' structures */
    329                 if (*pe == SML_PE_GENERIC) {
    330                     SmlGenericCmdPtr_t g = *ppContent;
    331                     switch ((int) ((pPEs+i)->tagid)) {
    332                     case TN_ADD    : g->elementType = SML_PE_ADD;     break;
    333                     case TN_COPY   : g->elementType = SML_PE_COPY;    break;
    334                     case TN_DELETE : g->elementType = SML_PE_DELETE;  break;
    335                     case TN_REPLACE: g->elementType = SML_PE_REPLACE; break;
    336                     }
    337                 }
    338                 break;
    339             }
    340             i++;
    341         }
    342         if (((pPEs+i)->tagid) == TN_UNDEF)
    343         {
    344                 *pe = SML_PE_UNDEF;
    345                 *ppContent = NULL;
    346                 smlLibFree(pPEs);
    347                 return SML_ERR_XLT_INVAL_PROTO_ELEM;
    348         }
    349         smlLibFree(pPEs);
    350     } else {
    351 
    352         /* found end tag */
    353         switch (pScanner->curtok->tagid) {
    354             case TN_ATOMIC:
    355                 *pe = SML_PE_ATOMIC_END;
    356                 *ppContent = NULL;
    357                 break;
    358             case TN_SEQUENCE:
    359                 *pe = SML_PE_SEQUENCE_END;
    360                 *ppContent = NULL;
    361                 break;
    362             case TN_SYNC:
    363                 *pe = SML_PE_SYNC_END;
    364                 *ppContent = NULL;
    365                 break;
    366             case TN_FINAL:
    367                 *pe = SML_PE_FINAL;
    368                 *ppContent = NULL;
    369                 pDecPriv->final = 1;
    370                 break;
    371             case TN_SYNCBODY:
    372                 /* next comes the SyncML end tag, then we're done */
    373                 if ((rc = nextToken(pDecPriv)) != SML_ERR_OK)
    374                     return rc;
    375                 if ((pScanner->curtok->type == TOK_TAG_END) &&
    376                         (pScanner->curtok->tagid == TN_SYNCML)) {
    377                     *pe = SML_PE_UNDEF;
    378                     *ppContent = NULL;
    379                     pDecPriv->finished = 1;
    380                 } else {
    381                     return SML_ERR_XLT_INVAL_SYNCML_DOC;
    382                 }
    383                 break;
    384             default:
    385                 return SML_ERR_XLT_INVAL_PROTO_ELEM;
    386         }
    387     }
    388 
    389     *ppBufPos = pScanner->getPos(pScanner);
    390 
    391     return SML_ERR_OK;
    392 }
    393 
    394 /**
    395  * Description see XLTDec.h header file.
    396  */
    397 Ret_t
    398 xltDecTerminate(XltDecoderPtr_t pDecoder)
    399 {
    400     XltDecoderPtr_t pDecPriv;
    401 
    402     if (pDecoder == NULL)
    403         return SML_ERR_OK;
    404 
    405     pDecPriv = (XltDecoderPtr_t)pDecoder;
    406     if (pDecPriv->scanner != NULL)
    407         pDecPriv->scanner->destroy(pDecPriv->scanner);
    408     if (pDecPriv->tagstack != NULL)
    409         pDecPriv->tagstack->destroy(pDecPriv->tagstack);
    410     smlLibFree(pDecPriv);
    411 
    412     return SML_ERR_OK;
    413 }
    414 
    415 
    416 Ret_t xltDecReset(XltDecoderPtr_t pDecoder)
    417 {
    418   return xltDecTerminate(pDecoder);
    419 }
    420 
    421 /**
    422  * Gets the next token from the scanner.
    423  * Checks if the current tag is an end tag and if so, whether the last
    424  * open start tag has the same tag id as the current end tag. An open start
    425  * tag is one which matching end tag has not been seen yet.
    426  * If the current tag is a start tag its tag ID will be pushed onto the
    427  * tag stack.
    428  * If the current tag is an empty tag or not a tag at all nothing will be
    429  * done.
    430  */
    431 Ret_t
    432 nextToken(XltDecoderPtr_t pDecoder)
    433 {
    434     XltUtilStackPtr_t pTagStack;
    435     XltDecTokenPtr_t pToken;
    436     Ret_t rc;
    437 
    438 #ifdef __USE_DMTND__
    439     // TODO
    440     if ( pDecoder->smlEncoding != pDecoder->tndsEncoding )
    441     {
    442         KCDBG("pDecoder->smlEncoding != pDecoder->tndsEncoding\n");
    443         return SML_ERR_OK;
    444     }
    445 #endif
    446 
    447     if ((rc = pDecoder->scanner->nextTok(pDecoder->scanner)) != SML_ERR_OK)
    448         return rc;
    449 
    450     pToken = pDecoder->scanner->curtok;
    451     pTagStack = pDecoder->tagstack;
    452 
    453     if (IS_START(pToken)) {
    454         if (pTagStack->push(pTagStack, pToken->tagid))
    455             return SML_ERR_UNSPECIFIC;
    456     } else if (IS_END(pToken)) {
    457         XltTagID_t lastopen;
    458         if (pTagStack->pop(pTagStack, &lastopen))
    459             return SML_ERR_UNSPECIFIC;
    460         if (pToken->tagid != lastopen)
    461             return SML_ERR_XLT_INVAL_SYNCML_DOC;
    462     }
    463     return SML_ERR_OK;
    464 }
    465 
    466 Ret_t discardToken(XltDecoderPtr_t pDecoder)
    467 
    468 {
    469     Ret_t rc;
    470     XltTagID_t tmp;
    471     if ((rc = pDecoder->scanner->pushTok(pDecoder->scanner)) != SML_ERR_OK)
    472         return rc;
    473     if ((rc = pDecoder->tagstack->pop(pDecoder->tagstack, &tmp)) != SML_ERR_OK)
    474         return rc;
    475     return SML_ERR_OK;
    476 }
    477 
    478 /*************************************************************************/
    479 /* Internal Functions                                                    */
    480 /*************************************************************************/
    481 
    482 static SmlPcdataPtr_t
    483 concatPCData(SmlPcdataPtr_t pDat1, const SmlPcdataPtr_t pDat2)
    484 {
    485     if (pDat1->contentType != pDat2->contentType)
    486         return NULL;
    487 
    488     switch (pDat1->contentType) {
    489         case SML_PCDATA_STRING:
    490             pDat1->content = (VoidPtr_t)smlLibStrcat(pDat1->content, pDat2->content);
    491             pDat1->length += pDat2->length;
    492             break;
    493         case SML_PCDATA_OPAQUE:
    494             if ((pDat1->content = smlLibRealloc(pDat1->content, pDat1->length + pDat2->length)) == NULL)
    495                 return NULL;
    496             smlLibMemmove(((Byte_t*)pDat1->content) + pDat1->length, pDat2->content, pDat2->length);
    497             pDat1->length += pDat2->length;
    498             break;
    499         default:
    500             return NULL;
    501     }
    502     return pDat1;
    503 }
    504 
    505 Ret_t
    506 buildSyncHdr(XltDecoderPtr_t pDecoder, VoidPtr_t *ppSyncHdr)
    507 {
    508     XltDecScannerPtr_t pScanner;
    509     SmlSyncHdrPtr_t pSyncHdr;
    510     Ret_t rc;
    511     Long_t sessionid = 0, msgid = 0, source = 0, target = 0, version = 0, proto = 0;
    512 
    513     /* shortcut to the scanner object */
    514     pScanner = pDecoder->scanner;
    515 
    516     /* if ppSyncHdr is not NULL we've already
    517        found a SyncHdr before! */
    518     if (*ppSyncHdr != NULL)
    519         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    520 
    521     /* initialize new SmlSyncHdr */
    522     if ((pSyncHdr = (SmlSyncHdrPtr_t)smlLibMalloc(sizeof(SmlSyncHdr_t))) == NULL)
    523         return SML_ERR_NOT_ENOUGH_SPACE;
    524     smlLibMemset(pSyncHdr, 0, sizeof(SmlSyncHdr_t));
    525 
    526     /* initialize the element type field */
    527     pSyncHdr->elementType = SML_PE_HEADER;
    528 
    529     /* empty SmlSyncHdr is possible */
    530     if (IS_EMPTY(pScanner->curtok)) {
    531         *ppSyncHdr = pSyncHdr;
    532         return SML_ERR_OK;
    533     }
    534 
    535     /* get next Token */
    536     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
    537         smlLibFree(pSyncHdr);
    538         return rc;
    539     }
    540 
    541     /* parse child elements until we find a matching end tag */
    542     while (pScanner->curtok->type != TOK_TAG_END) {
    543         switch (pScanner->curtok->tagid) {
    544 
    545             /* PCDATA elements */
    546             case TN_VERSION:
    547                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->version);
    548                 version++;
    549                 break;
    550             case TN_PROTO:
    551                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->proto);
    552                 proto++;
    553                 break;
    554             case TN_SESSIONID:
    555                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->sessionID);
    556                 sessionid++;
    557                 break;
    558             case TN_MSGID:
    559                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->msgID);
    560                 msgid++;
    561                 break;
    562             case TN_RESPURI:
    563                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->respURI);
    564                 break;
    565 
    566                 /* child tags */
    567             case TN_TARGET:
    568                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pSyncHdr->target);
    569                 target++;
    570                 break;
    571             case TN_SOURCE:
    572                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pSyncHdr->source);
    573                 source++;
    574                 break;
    575             case TN_CRED:
    576                 rc = buildCred(pDecoder, (VoidPtr_t)&pSyncHdr->cred);
    577                 break;
    578             case TN_META:
    579                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSyncHdr->meta);
    580                 break;
    581 
    582                 /* flags (empty tags) */
    583             case TN_NORESP:
    584                 pSyncHdr->flags |= SmlNoResp_f;
    585                 break;
    586 
    587             default:
    588                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
    589         }
    590 
    591         /* decoding of child element went ok? */
    592         if (rc != SML_ERR_OK) {
    593             smlFreeSyncHdr(pSyncHdr);
    594 
    595             return rc;
    596         }
    597 
    598         /* get next token */
    599         if ((rc = nextToken(pDecoder)) != SML_ERR_OK) {
    600             smlFreeSyncHdr(pSyncHdr);
    601             return rc;
    602         }
    603     }
    604 
    605     if ((sessionid == 0) || (msgid == 0) || (target == 0) || (source == 0) || (version == 0) || (proto == 0))
    606     {
    607       smlFreeSyncHdr(pSyncHdr);
    608       return SML_ERR_XLT_INVAL_SYNCML_DOC;
    609     }
    610 
    611     *ppSyncHdr = pSyncHdr;
    612 
    613     return SML_ERR_OK;
    614 }
    615 
    616 Ret_t
    617 buildSync(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem)
    618 {
    619     XltDecScannerPtr_t pScanner;
    620     SmlSyncPtr_t pSync;
    621     Ret_t rc;
    622     Long_t cmdid = 0;
    623 
    624     /* stop decoding the Sync when we find a SyncML command */
    625     Byte_t break_sync = 0;
    626 
    627     pScanner = pDecoder->scanner;
    628 
    629     if (*ppElem != NULL)
    630         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    631 
    632     /* initialize a new Sync */
    633     if ((pSync = (SmlSyncPtr_t)smlLibMalloc(sizeof(SmlSync_t))) == NULL)
    634         return SML_ERR_NOT_ENOUGH_SPACE;
    635     smlLibMemset(pSync, 0, sizeof(SmlSync_t));
    636 
    637     /* initialize the element type field */
    638     pSync->elementType = SML_PE_SYNC_START;
    639 
    640     if (IS_EMPTY(pScanner->curtok)) {
    641 
    642         smlLibFree(pSync);
    643         return SML_ERR_OK;
    644     }
    645 
    646     /* get next token */
    647     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
    648         smlLibFree(pSync);
    649         return rc;
    650     }
    651 
    652     /* parse child elements until we find a matching end tag
    653        or until we find a TN_ADD, TN_ATOMIC, etc. start tag */
    654     while ((pScanner->curtok->type != TOK_TAG_END) && !break_sync) {
    655         switch (pScanner->curtok->tagid) {
    656 
    657             /* PCDATA elements */
    658             case TN_CMDID:
    659                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSync->cmdID);
    660                 cmdid++;
    661                 break;
    662             case TN_META:
    663                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSync->meta);
    664                 break;
    665             case TN_NUMBEROFCHANGES:
    666                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSync->noc);
    667                 break;
    668 
    669                 /* child tags */
    670             case TN_CRED:
    671                 rc = buildCred(pDecoder, (VoidPtr_t)&pSync->cred);
    672                 break;
    673             case TN_TARGET:
    674                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pSync->target);
    675                 break;
    676             case TN_SOURCE:
    677                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pSync->source);
    678                 break;
    679 
    680                 /* flags */
    681             case TN_NORESP:
    682                 pSync->flags |= SmlNoResp_f;
    683                 break;
    684 
    685                 /* quit if we find an Add, Atomic, etc.
    686                    element */
    687             case TN_ADD:
    688             case TN_ATOMIC:
    689             case TN_COPY:
    690             case TN_DELETE:
    691             case TN_SEQUENCE:
    692             case TN_REPLACE:
    693                 break_sync = 1;
    694                 break;
    695 
    696             default:
    697                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
    698         }
    699         if (rc != SML_ERR_OK) {
    700             smlFreeSync(pSync);
    701             return rc;
    702         }
    703         if (!break_sync) {
    704             /* get next token and continue as usual */
    705             if ((rc = nextToken(pDecoder)) != SML_ERR_OK) {
    706                 smlFreeSync(pSync);
    707                 return rc;
    708             }
    709         } else {
    710             /* we've found a SyncML command - we need to go
    711                back one token and correct the tagstack */
    712             if ((rc = discardToken(pDecoder)) != SML_ERR_OK) {
    713                 smlFreeSync(pSync);
    714                 return rc;
    715             }
    716         }
    717     }
    718 
    719     if (!break_sync)  {
    720       if ((pScanner->curtok->tagid) != TN_SYNC)
    721       {
    722         smlFreeSync(pSync);
    723         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    724       }
    725       else
    726       {
    727 		 if (pDecoder->tagstack->push(pDecoder->tagstack, pScanner->curtok->tagid))
    728          {
    729             smlFreeSync(pSync);
    730             return SML_ERR_UNSPECIFIC;
    731          }
    732          if ((rc = pDecoder->scanner->pushTok(pDecoder->scanner)) != SML_ERR_OK)
    733          {
    734            smlFreeSync(pSync);
    735            return rc;
    736          }
    737       }
    738     }
    739 
    740     *ppElem = pSync;
    741 
    742     return SML_ERR_OK;
    743 }
    744 
    745 #if (defined ATOMIC_RECEIVE || defined SEQUENCE_RECEIVE)
    746 Ret_t
    747 buildAtomOrSeq(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem)
    748 {
    749     XltDecScannerPtr_t pScanner;
    750     SmlAtomicPtr_t pAoS;        /* SmlAtomicPtr_t and SequencePtr_t are pointer
    751                                 to the same structure! */
    752     Ret_t rc;
    753     Byte_t break_aos = 0;    /* stop decoding the Atomic when we find a
    754                                 SyncML command */
    755     Long_t cmdid = 0;
    756 
    757     pScanner = pDecoder->scanner;
    758 
    759     if (*ppElem != NULL)
    760         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    761 
    762     if ((pAoS = (SmlAtomicPtr_t)smlLibMalloc(sizeof(SmlAtomic_t))) == NULL)
    763         return SML_ERR_NOT_ENOUGH_SPACE;
    764     smlLibMemset(pAoS, 0, sizeof(SmlAtomic_t));
    765 
    766     /* initialize the element type field */
    767     pAoS->elementType = SML_PE_CMD_GROUP;
    768 
    769     if (IS_EMPTY(pScanner->curtok)) {
    770         smlLibFree(pAoS);
    771         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    772     }
    773 
    774     /* get next token */
    775     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
    776         smlLibFree (pAoS);
    777         return rc;
    778     }
    779 
    780     /* parse child elements until we find a matching end tag
    781        or until we find a TN_ADD, TN_ATOMIC, etc. start tag */
    782     while ((pScanner->curtok->type != TOK_TAG_END) && !break_aos) {
    783         switch (pScanner->curtok->tagid) {
    784 
    785             /* PCDATA elements */
    786             case TN_CMDID:
    787                 rc = buildPCData(pDecoder, (VoidPtr_t)&pAoS->cmdID);
    788                 cmdid++;
    789                 break;
    790             case TN_META:
    791                 rc = buildPCData(pDecoder, (VoidPtr_t)&pAoS->meta);
    792                 break;
    793 
    794                 /* flags */
    795             case TN_NORESP:
    796                 pAoS->flags |= SmlNoResp_f;
    797                 break;
    798 
    799                 /* quit if we find an Add, Atomic, etc.
    800                    element */
    801             case TN_ADD:
    802             case TN_REPLACE:
    803             case TN_DELETE:
    804             case TN_COPY:
    805             case TN_ATOMIC:
    806             case TN_MAP:
    807             case TN_SYNC:
    808 			case TN_GET:
    809 			case TN_ALERT:
    810 			case TN_EXEC:
    811                 break_aos = 1;
    812                 break;
    813 
    814             default:
    815                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
    816         }
    817         if (rc != SML_ERR_OK) {
    818             smlFreeAtomic(pAoS);
    819             return rc;
    820         }
    821         if (!break_aos) {
    822             if ((rc = nextToken(pDecoder)) != SML_ERR_OK) {
    823                 smlFreeAtomic(pAoS);
    824                 return rc;
    825             }
    826         } else {
    827             /* we've found a SyncML command - we need to go
    828                back one token and correct the tagstack */
    829             if ((rc = discardToken(pDecoder)) != SML_ERR_OK) {
    830                 smlFreeAtomic(pAoS);
    831                 return rc;
    832             }
    833         }
    834     }
    835 
    836     if (!break_aos) {
    837         /* Atomic/Sequence must contain at least one SyncML command */
    838         smlFreeAtomic(pAoS);
    839         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    840     }
    841 
    842     if (cmdid == 0)
    843     {
    844         smlFreeAtomic(pAoS);
    845         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    846     }
    847 
    848     *ppElem = pAoS;
    849 
    850     return SML_ERR_OK;
    851 }
    852 #endif
    853 
    854 #ifdef EXEC_RECEIVE
    855 Ret_t
    856 buildExec(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem)
    857 {
    858     XltDecScannerPtr_t pScanner;
    859     SmlExecPtr_t pExec;
    860     Ret_t rc;
    861     Long_t items = 0, cmdid = 0;
    862 
    863     pScanner = pDecoder->scanner;
    864 
    865     if (*ppElem != NULL)
    866         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    867 
    868     if ((pExec = (SmlExecPtr_t)smlLibMalloc(sizeof(SmlExec_t))) == NULL)
    869         return SML_ERR_NOT_ENOUGH_SPACE;
    870     smlLibMemset(pExec, 0, sizeof(SmlExec_t));
    871 
    872     /* initialize the element type field */
    873     pExec->elementType = SML_PE_EXEC;
    874 
    875     if (IS_EMPTY(pScanner->curtok)) {
    876         smlLibFree(pExec);
    877         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    878     }
    879 
    880     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
    881         smlLibFree(pExec);
    882         return rc;
    883     }
    884 
    885     while (pScanner->curtok->type != TOK_TAG_END) {
    886         switch (pScanner->curtok->tagid) {
    887 
    888             /* PCData */
    889             case TN_CMDID:
    890                 rc = buildPCData(pDecoder, (VoidPtr_t)&pExec->cmdID);
    891                 cmdid++;
    892                 break;
    893 
    894             case TN_CORRELATOR:
    895                 rc = buildPCData(pDecoder, (VoidPtr_t)&pExec->correlator);
    896                 break;
    897 
    898            case TN_META:
    899                 rc = buildPCData(pDecoder, (VoidPtr_t)&pExec->meta);
    900                 break;
    901 
    902                 /* child tags */
    903             case TN_CRED:
    904                 rc = buildCred(pDecoder, (VoidPtr_t)&pExec->cred);
    905                 break;
    906 
    907             case TN_ITEM:
    908                 rc = buildItem(pDecoder, (VoidPtr_t)&pExec->item);
    909                 items++;
    910                 break;
    911 
    912                 /* flags */
    913             case TN_NORESP:
    914                 pExec->flags |= SmlNoResp_f;
    915                 break;
    916 
    917             default:
    918                 rc =  SML_ERR_XLT_INVAL_SYNCML_DOC;
    919         }
    920         if (rc != SML_ERR_OK) {
    921             smlFreeExec(pExec);
    922             return rc;
    923         }
    924         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
    925             smlFreeExec(pExec);
    926             return rc;
    927         }
    928     }
    929 
    930     if ((items == 0) || (cmdid == 0)) {
    931         smlFreeExec(pExec);
    932         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    933     }
    934 
    935     *ppElem = pExec;
    936 
    937     return SML_ERR_OK;
    938 }
    939 #endif
    940 
    941 Ret_t
    942 buildGenericCmd(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem)
    943 {
    944     XltDecScannerPtr_t pScanner;
    945     SmlGenericCmdPtr_t pGenCmd;
    946     Ret_t rc;
    947     Long_t items = 0, cmdid = 0;
    948 
    949     pScanner = pDecoder->scanner;
    950 
    951     if (*ppElem != NULL)
    952         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    953 
    954     /* initialize a new GenericCmd */
    955     if ((pGenCmd = (SmlGenericCmdPtr_t)smlLibMalloc(sizeof(SmlGenericCmd_t))) == NULL)
    956         return SML_ERR_NOT_ENOUGH_SPACE;
    957     smlLibMemset(pGenCmd, 0, sizeof(SmlGenericCmd_t));
    958 
    959     /* initialize the element type field */
    960     pGenCmd->elementType = SML_PE_GENERIC;
    961 
    962     if (IS_EMPTY(pScanner->curtok)) {
    963         smlLibFree(pGenCmd);
    964         return SML_ERR_XLT_INVAL_SYNCML_DOC;
    965     }
    966 
    967     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
    968         smlLibFree(pGenCmd);
    969         return rc;
    970     }
    971 
    972     while (pScanner->curtok->type != TOK_TAG_END) {
    973         switch (pScanner->curtok->tagid) {
    974 
    975             /* PCDATA elements */
    976             case TN_CMDID:
    977                 rc = buildPCData(pDecoder, (VoidPtr_t)&pGenCmd->cmdID);
    978                 cmdid++;
    979                 break;
    980             case TN_META:
    981                 rc = buildPCData(pDecoder, (VoidPtr_t)&pGenCmd->meta);
    982                 break;
    983 
    984                 /* child tags */
    985             case TN_CRED:
    986                 rc = buildCred(pDecoder, (VoidPtr_t)&pGenCmd->cred);
    987                 break;
    988 
    989                 /* flags (empty tags) */
    990             case TN_NORESP:
    991                 pGenCmd->flags |= SmlNoResp_f;
    992                 break;
    993             case TN_ARCHIVE:
    994                 pGenCmd->flags |= SmlArchive_f;
    995                 break;
    996             case TN_SFTDEL:
    997                 pGenCmd->flags |= SmlSftDel_f;
    998                 break;
    999 
   1000                 /* Lists */
   1001             case TN_ITEM:
   1002                 rc = appendItemList(pDecoder, &pGenCmd->itemList);
   1003                 items++;
   1004                 break;
   1005 
   1006             default:
   1007                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1008         }
   1009         if (rc != SML_ERR_OK) {
   1010             smlFreeGeneric(pGenCmd);
   1011             return rc;
   1012         }
   1013         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1014             smlFreeGeneric(pGenCmd);
   1015             return rc;
   1016         }
   1017     }
   1018 
   1019     if ((items == 0) || (cmdid == 0))
   1020     {
   1021         smlFreeGeneric(pGenCmd);
   1022         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1023     }
   1024 
   1025     *ppElem = pGenCmd;
   1026 
   1027     return SML_ERR_OK;
   1028 }
   1029 
   1030 Ret_t
   1031 buildAlert(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem)
   1032 {
   1033     XltDecScannerPtr_t pScanner;
   1034     SmlAlertPtr_t pAlert;
   1035     Ret_t rc;
   1036     Long_t cmdid = 0;
   1037 
   1038     pScanner = pDecoder->scanner;
   1039 
   1040     if (*ppElem != NULL)
   1041         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1042 
   1043     if ((pAlert = (SmlAlertPtr_t)smlLibMalloc(sizeof(SmlAlert_t))) == NULL)
   1044         return SML_ERR_NOT_ENOUGH_SPACE;
   1045     smlLibMemset(pAlert, 0, sizeof(SmlAlert_t));
   1046 
   1047     /* initialize the element type field */
   1048     pAlert->elementType = SML_PE_ALERT;
   1049 
   1050     if (IS_EMPTY(pScanner->curtok)) {
   1051         smlLibFree(pAlert);
   1052         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1053     }
   1054 
   1055     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1056         smlLibFree(pAlert);
   1057         return rc;
   1058     }
   1059 
   1060     while (pScanner->curtok->type != TOK_TAG_END) {
   1061         switch (pScanner->curtok->tagid) {
   1062 
   1063             /* PCDATA elements */
   1064             case TN_CMDID:
   1065                 rc = buildPCData(pDecoder, (VoidPtr_t)&pAlert->cmdID);
   1066                 cmdid++;
   1067                 break;
   1068 
   1069             case TN_CORRELATOR:
   1070                 rc = buildPCData(pDecoder, (VoidPtr_t)&pAlert->correlator);
   1071                 break;
   1072 
   1073             case TN_DATA:
   1074                 rc = buildPCData(pDecoder, (VoidPtr_t)&pAlert->data);
   1075                 break;
   1076 
   1077                 /* child tags */
   1078             case TN_CRED:
   1079                 rc = buildCred(pDecoder, (VoidPtr_t)&pAlert->cred);
   1080                 break;
   1081 
   1082                 /* flags (empty tags) */
   1083             case TN_NORESP:
   1084                 pAlert->flags |= SmlNoResp_f;
   1085                 break;
   1086 
   1087                 /* Lists */
   1088             case TN_ITEM:
   1089                 rc = appendItemList(pDecoder, &pAlert->itemList);
   1090                 break;
   1091 
   1092             default:
   1093                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1094         }
   1095         if (rc != SML_ERR_OK) {
   1096             smlFreeAlert(pAlert);
   1097             return rc;
   1098         }
   1099         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1100             smlFreeAlert(pAlert);
   1101             return rc;
   1102         }
   1103     }
   1104 
   1105     if (cmdid == 0)
   1106     {
   1107         smlFreeAlert(pAlert);
   1108         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1109     }
   1110 
   1111     *ppElem = pAlert;
   1112 
   1113     return SML_ERR_OK;
   1114 }
   1115 
   1116 #ifdef MAP_RECEIVE
   1117 Ret_t
   1118 buildMap(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem)
   1119 {
   1120     XltDecScannerPtr_t pScanner;
   1121     SmlMapPtr_t pMap;
   1122     Ret_t rc;
   1123     Long_t target = 0, source = 0, mapitems = 0, cmdid = 0;
   1124 
   1125     pScanner = pDecoder->scanner;
   1126 
   1127     if (*ppElem != NULL)
   1128         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1129 
   1130     if ((pMap = (SmlMapPtr_t)smlLibMalloc(sizeof(SmlMap_t))) == NULL)
   1131         return SML_ERR_NOT_ENOUGH_SPACE;
   1132     smlLibMemset(pMap, 0, sizeof(SmlMap_t));
   1133 
   1134     /* initialize the element type field */
   1135     pMap->elementType = SML_PE_MAP;
   1136 
   1137     /* Source is required */
   1138     if (IS_EMPTY(pScanner->curtok)) {
   1139         smlLibFree(pMap);
   1140         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1141     }
   1142 
   1143     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1144         smlLibFree(pMap);
   1145         return rc;
   1146     }
   1147 
   1148     while (pScanner->curtok->type != TOK_TAG_END) {
   1149         switch (pScanner->curtok->tagid) {
   1150 
   1151             /* PCDATA elements */
   1152             case TN_CMDID:
   1153                 rc = buildPCData(pDecoder, (VoidPtr_t)&pMap->cmdID);
   1154                 cmdid++;
   1155                 break;
   1156             case TN_META:
   1157                 rc = buildPCData(pDecoder, (VoidPtr_t)&pMap->meta);
   1158                 break;
   1159 
   1160                 /* child tags */
   1161             case TN_CRED:
   1162                 rc = buildCred(pDecoder, (VoidPtr_t)&pMap->cred);
   1163                 break;
   1164             case TN_SOURCE:
   1165                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pMap->source);
   1166                 source++;
   1167                 break;
   1168             case TN_TARGET:
   1169                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pMap->target);
   1170                 target++;
   1171                 break;
   1172 #ifdef MAPITEM_RECEIVE
   1173                 /* Lists */
   1174             case TN_MAPITEM:
   1175                 rc = appendMapItemList(pDecoder, &pMap->mapItemList);
   1176                 mapitems++;
   1177                 break;
   1178 #endif
   1179             default:
   1180                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1181         }
   1182         if (rc != SML_ERR_OK) {
   1183             smlFreeMap(pMap);
   1184             return rc;
   1185         }
   1186         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1187             smlFreeMap(pMap);
   1188             return rc;
   1189         }
   1190     }
   1191 
   1192     if ((source == 0) || (mapitems == 0) || (target == 0) || (cmdid == 0)) {
   1193         smlFreeMap(pMap);
   1194         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1195     }
   1196 
   1197     *ppElem = pMap;
   1198 
   1199     return SML_ERR_OK;
   1200 }
   1201 #endif
   1202 
   1203 #ifdef SEARCH_RECEIVE
   1204 Ret_t
   1205 buildSearch(XltDecoderPtr_t pDecoder, VoidPtr_t *ppSearch)
   1206 {
   1207     XltDecScannerPtr_t pScanner;
   1208     SmlSearchPtr_t pSearch;
   1209     Ret_t rc;
   1210     Long_t source = 0, meta = 0, data = 0, cmdid = 0;
   1211 
   1212     pScanner = pDecoder->scanner;
   1213 
   1214     if (*ppSearch != NULL)
   1215         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1216 
   1217     if ((pSearch = (SmlSearchPtr_t)smlLibMalloc(sizeof(SmlSearch_t))) == NULL)
   1218         return SML_ERR_NOT_ENOUGH_SPACE;
   1219     smlLibMemset(pSearch, 0, sizeof(SmlSearch_t));
   1220 
   1221     /* initialize the element type field */
   1222     pSearch->elementType = SML_PE_SEARCH;
   1223 
   1224     /* Meta is required */
   1225     if (IS_EMPTY(pScanner->curtok)) {
   1226         smlLibFree(pSearch);
   1227         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1228     }
   1229 
   1230     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1231         smlLibFree(pSearch);
   1232         return rc;
   1233     }
   1234 
   1235     while (pScanner->curtok->type != TOK_TAG_END) {
   1236         switch (pScanner->curtok->tagid) {
   1237 
   1238             /* PCDATA elements */
   1239             case TN_CMDID:
   1240                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSearch->cmdID);
   1241                 cmdid++;
   1242                 break;
   1243             case TN_LANG:
   1244                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSearch->lang);
   1245                 break;
   1246             case TN_META:
   1247                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSearch->meta);
   1248                 meta++;
   1249                 break;
   1250             case TN_DATA:
   1251                 rc = buildPCData(pDecoder, (VoidPtr_t)&pSearch->data);
   1252                 data++;
   1253                 break;
   1254 
   1255 
   1256                 /* child tags */
   1257             case TN_CRED:
   1258                 rc = buildCred(pDecoder, (VoidPtr_t)&pSearch->cred);
   1259                 break;
   1260             case TN_TARGET:
   1261                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pSearch->target);
   1262                 break;
   1263 
   1264                 /* flags */
   1265             case TN_NORESP:
   1266                 pSearch->flags |= SmlNoResp_f;
   1267                 break;
   1268             case TN_NORESULTS:
   1269                 pSearch->flags |= SmlNoResults_f;
   1270                 break;
   1271 
   1272                 /* Lists */
   1273             case TN_SOURCE:
   1274                 rc = appendSourceList(pDecoder, &pSearch->sourceList);
   1275                 source++;
   1276                 break;
   1277 
   1278             default:
   1279                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1280         }
   1281         if (rc != SML_ERR_OK) {
   1282             smlFreeSearch(pSearch);
   1283             return rc;
   1284         }
   1285         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1286             smlFreeSearch(pSearch);
   1287             return rc;
   1288         }
   1289     }
   1290 
   1291     if ((source == 0) || (meta == 0) || (data == 0) || (cmdid == 0)) {
   1292         smlFreeSearch(pSearch);
   1293         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1294     }
   1295 
   1296     *ppSearch = pSearch;
   1297 
   1298     return SML_ERR_OK;
   1299 }
   1300 #endif
   1301 
   1302 Ret_t
   1303 buildPutOrGet(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem)
   1304 {
   1305     XltDecScannerPtr_t pScanner;
   1306     SmlGetPtr_t pGet;
   1307     Ret_t rc;
   1308     Long_t items = 0, cmdid = 0;
   1309 
   1310     pScanner = pDecoder->scanner;
   1311 
   1312     if (*ppElem != NULL)
   1313         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1314 
   1315     if ((pGet = (SmlGetPtr_t)smlLibMalloc(sizeof(SmlGet_t))) == NULL)
   1316         return SML_ERR_NOT_ENOUGH_SPACE;
   1317     smlLibMemset(pGet, 0, sizeof(SmlGet_t));
   1318 
   1319     /* initialize the element type field */
   1320     pGet->elementType = SML_PE_PUT_GET;
   1321 
   1322     if (IS_EMPTY(pScanner->curtok)) {
   1323         smlLibFree(pGet);
   1324         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1325     }
   1326 
   1327     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1328         smlLibFree(pGet);
   1329         return rc;
   1330     }
   1331 
   1332     while (pScanner->curtok->type != TOK_TAG_END) {
   1333         switch (pScanner->curtok->tagid) {
   1334 
   1335             /* PCDATA elements */
   1336             case TN_CMDID:
   1337                 rc = buildPCData(pDecoder, (VoidPtr_t)&pGet->cmdID);
   1338                 cmdid++;
   1339                 break;
   1340             case TN_LANG:
   1341                 rc = buildPCData(pDecoder, (VoidPtr_t)&pGet->lang);
   1342                 break;
   1343             case TN_META:
   1344                 rc = buildPCData(pDecoder, (VoidPtr_t)&pGet->meta);
   1345                 break;
   1346 
   1347                 /* child tags */
   1348             case TN_CRED:
   1349                 rc = buildCred(pDecoder, (VoidPtr_t)&pGet->cred);
   1350                 break;
   1351 
   1352                 /* flags */
   1353             case TN_NORESP:
   1354                 pGet->flags |= SmlNoResp_f;
   1355                 break;
   1356 
   1357                 /* Lists */
   1358 
   1359             case TN_ITEM:
   1360                 rc = appendItemList(pDecoder, &pGet->itemList);
   1361                 items++;
   1362                 break;
   1363 
   1364             default:
   1365                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1366         }
   1367         if (rc != SML_ERR_OK) {
   1368             smlFreeGetPut(pGet);
   1369             return rc;
   1370         }
   1371         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1372             smlFreeGetPut(pGet);
   1373             return rc;
   1374         }
   1375     }
   1376 
   1377     if ((items == 0) || (cmdid == 0))
   1378     {
   1379         smlFreeGetPut(pGet);
   1380         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1381     }
   1382 
   1383     *ppElem = pGet;
   1384 
   1385     return SML_ERR_OK;
   1386 }
   1387 
   1388 Ret_t
   1389 buildTargetOrSource(XltDecoderPtr_t pDecoder, VoidPtr_t *ppTarget)
   1390 {
   1391     XltDecScannerPtr_t pScanner;
   1392     SmlTargetPtr_t pTarget;
   1393     Long_t locuri = 0;
   1394     Ret_t rc;
   1395 
   1396     pScanner = pDecoder->scanner;
   1397 
   1398     if (*ppTarget != NULL)
   1399         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1400 
   1401     if ((pTarget = (SmlTargetPtr_t)smlLibMalloc(sizeof(SmlTarget_t))) == NULL)
   1402         return SML_ERR_NOT_ENOUGH_SPACE;
   1403     smlLibMemset(pTarget, 0, sizeof(SmlTarget_t));
   1404 
   1405     if (IS_EMPTY(pScanner->curtok)) {
   1406         smlLibFree(pTarget);
   1407         return SML_ERR_OK;
   1408     }
   1409 
   1410     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1411         smlLibFree(pTarget);
   1412         return rc;
   1413     }
   1414 
   1415     while (pScanner->curtok->type != TOK_TAG_END) {
   1416         switch (pScanner->curtok->tagid) {
   1417 
   1418             /* PCDATA elements */
   1419             case TN_LOCURI:
   1420                 rc = buildPCData(pDecoder, (VoidPtr_t)&pTarget->locURI);
   1421                 locuri++;
   1422                 break;
   1423             case TN_LOCNAME:
   1424                 rc = buildPCData(pDecoder, (VoidPtr_t)&pTarget->locName);
   1425                 break;
   1426 
   1427             default:
   1428                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1429         }
   1430         if (rc != SML_ERR_OK) {
   1431 	    if(pScanner->curtok->pcdata != NULL)
   1432 		    smlLibFree(pScanner->curtok->pcdata->content);
   1433 	    smlLibFree(pScanner->curtok->pcdata);
   1434             smlFreeSourceTargetPtr(pTarget);
   1435             return rc;
   1436         }
   1437         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1438             smlFreeSourceTargetPtr(pTarget);
   1439             return rc;
   1440         }
   1441     }
   1442 
   1443     if (locuri == 0)
   1444     {
   1445         smlFreeSourceTargetPtr(pTarget);
   1446         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1447     }
   1448 
   1449     *ppTarget = pTarget;
   1450 
   1451     return SML_ERR_OK;
   1452 }
   1453 
   1454 Ret_t
   1455 buildChal(XltDecoderPtr_t pDecoder, VoidPtr_t *ppChal)
   1456 {
   1457     XltDecScannerPtr_t pScanner;
   1458     SmlChalPtr_t pChal;
   1459     Long_t meta = 0;
   1460     Ret_t rc;
   1461 
   1462     pScanner = pDecoder->scanner;
   1463 
   1464     if (*ppChal != NULL)
   1465         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1466 
   1467     if ((pChal = (SmlChalPtr_t)smlLibMalloc(sizeof(SmlChal_t))) == NULL)
   1468         return SML_ERR_NOT_ENOUGH_SPACE;
   1469     smlLibMemset(pChal, 0, sizeof(SmlChal_t));
   1470 
   1471     if (IS_EMPTY(pScanner->curtok)) {
   1472         *ppChal = pChal;
   1473         return SML_ERR_OK;
   1474     }
   1475 
   1476     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1477         smlLibFree(pChal);
   1478         return rc;
   1479     }
   1480 
   1481     while (pScanner->curtok->type != TOK_TAG_END) {
   1482         switch (pScanner->curtok->tagid) {
   1483 
   1484             /* PCDATA elements */
   1485             case TN_META:
   1486                 rc = buildPCData(pDecoder, (VoidPtr_t)&pChal->meta);
   1487                 meta++;
   1488                 break;
   1489 
   1490             default:
   1491                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1492         }
   1493         if (rc != SML_ERR_OK) {
   1494             smlFreeChalPtr(pChal);
   1495             return rc;
   1496         }
   1497         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1498             smlFreeChalPtr(pChal);
   1499             return rc;
   1500         }
   1501     }
   1502 
   1503     if (meta == 0)
   1504     {
   1505         smlFreeChalPtr(pChal);
   1506         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1507     }
   1508 
   1509     *ppChal = pChal;
   1510 
   1511     return SML_ERR_OK;
   1512 }
   1513 
   1514 Ret_t
   1515 buildCred(XltDecoderPtr_t pDecoder, VoidPtr_t *ppCred)
   1516 {
   1517     XltDecScannerPtr_t pScanner;
   1518     SmlCredPtr_t pCred;
   1519     Ret_t rc;
   1520     Long_t data = 0;
   1521 
   1522     pScanner = pDecoder->scanner;
   1523 
   1524     if (*ppCred != NULL)
   1525         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1526 
   1527     if ((pCred = (SmlCredPtr_t)smlLibMalloc(sizeof(SmlCred_t))) == NULL)
   1528         return SML_ERR_NOT_ENOUGH_SPACE;
   1529     smlLibMemset(pCred, 0, sizeof(SmlCred_t));
   1530 
   1531     if (IS_EMPTY(pScanner->curtok)) {
   1532         *ppCred = pCred;
   1533         return SML_ERR_OK;
   1534     }
   1535 
   1536     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1537         smlLibFree(pCred);
   1538         return rc;
   1539     }
   1540 
   1541     while (pScanner->curtok->type != TOK_TAG_END) {
   1542         switch (pScanner->curtok->tagid) {
   1543 
   1544             /* PCDATA elements */
   1545             case TN_DATA:
   1546                 rc = buildPCData(pDecoder, (VoidPtr_t)&pCred->data);
   1547                 data++;
   1548                 break;
   1549             case TN_META:
   1550                 rc = buildPCData(pDecoder, (VoidPtr_t)&pCred->meta);
   1551                 break;
   1552 
   1553             default:
   1554                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1555         }
   1556         if (rc != SML_ERR_OK) {
   1557             smlFreeCredPtr(pCred);
   1558             return rc;
   1559         }
   1560         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1561             smlFreeCredPtr(pCred);
   1562             return rc;
   1563         }
   1564     }
   1565 
   1566     if (data == 0)
   1567     {
   1568       smlFreeCredPtr(pCred);
   1569       return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1570     }
   1571 
   1572     *ppCred = pCred;
   1573 
   1574     return SML_ERR_OK;
   1575 }
   1576 
   1577 Ret_t
   1578 buildItem(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem)
   1579 {
   1580     XltDecScannerPtr_t pScanner;
   1581     SmlItemPtr_t pItem;
   1582     Ret_t rc;
   1583 
   1584     pScanner = pDecoder->scanner;
   1585 
   1586     if (*ppElem != NULL)
   1587         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1588 
   1589     if ((pItem = (SmlItemPtr_t)smlLibMalloc(sizeof(SmlItem_t))) == NULL)
   1590         return SML_ERR_NOT_ENOUGH_SPACE;
   1591     smlLibMemset(pItem, 0, sizeof(SmlItem_t));
   1592 
   1593     /* Item might be empty */
   1594     if (IS_EMPTY(pScanner->curtok)) {
   1595         *ppElem = pItem;
   1596         return SML_ERR_OK;
   1597     }
   1598 
   1599     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1600         smlLibFree(pItem);
   1601         return rc;
   1602     }
   1603 
   1604     while (pScanner->curtok->type != TOK_TAG_END) {
   1605         switch (pScanner->curtok->tagid) {
   1606 
   1607             /* PCDATA elements */
   1608             case TN_META:
   1609                 rc = buildPCData(pDecoder, (VoidPtr_t)&pItem->meta);
   1610                 break;
   1611             case TN_DATA:
   1612                 rc = buildPCData(pDecoder, (VoidPtr_t)&pItem->data);
   1613 #ifdef __USE_EXTENSIONS__
   1614 #ifdef __SML_WBXML__
   1615                 if (pItem->data && pItem->data->contentType == SML_PCDATA_OPAQUE)
   1616                     subdtdDecodeWbxml(pDecoder, (SmlPcdataPtr_t*)&pItem->data);
   1617 #endif
   1618 #endif
   1619                 break;
   1620                 /* child tags */
   1621             case TN_TARGET:
   1622                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pItem->target);
   1623                 break;
   1624             case TN_SOURCE:
   1625                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pItem->source);
   1626                 break;
   1627 
   1628             /* flags */
   1629             case TN_MOREDATA:
   1630                 pItem->flags |= SmlMoreData_f;
   1631                 break;
   1632 
   1633             default:
   1634                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1635         }
   1636         if (rc != SML_ERR_OK) {
   1637             smlFreeItemPtr(pItem);
   1638             return rc;
   1639         }
   1640         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1641             smlFreeItemPtr(pItem);
   1642             return rc;
   1643         }
   1644     }
   1645 
   1646     *ppElem = pItem;
   1647 
   1648     return SML_ERR_OK;
   1649 }
   1650 
   1651 #ifdef MAPITEM_RECEIVE
   1652 Ret_t
   1653 buildMapItem(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem)
   1654 {
   1655     XltDecScannerPtr_t pScanner;
   1656     SmlMapItemPtr_t pMapItem;
   1657     Long_t target = 0, source = 0;
   1658     Ret_t rc;
   1659 
   1660     if (*ppElem != NULL)
   1661         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1662 
   1663     pScanner = pDecoder->scanner;
   1664 
   1665     if ((pMapItem = (SmlMapItemPtr_t)smlLibMalloc(sizeof(SmlMapItem_t))) == NULL)
   1666         return SML_ERR_NOT_ENOUGH_SPACE;
   1667     smlLibMemset(pMapItem, 0, sizeof(SmlMapItem_t));
   1668 
   1669     if (IS_EMPTY(pScanner->curtok)) {
   1670         smlLibFree(pMapItem);
   1671         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1672     }
   1673 
   1674     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1675         smlLibFree(pMapItem);
   1676         return rc;
   1677     }
   1678 
   1679     while (pScanner->curtok->type != TOK_TAG_END) {
   1680         switch (pScanner->curtok->tagid) {
   1681             /* child tags */
   1682             case TN_TARGET:
   1683                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pMapItem->target);
   1684                 target++;
   1685                 break;
   1686             case TN_SOURCE:
   1687                 rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pMapItem->source);
   1688                 source++;
   1689                 break;
   1690 
   1691             default:
   1692                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1693         }
   1694         if (rc != SML_ERR_OK) {
   1695             smlFreeMapItemPtr(pMapItem);
   1696             return rc;
   1697         }
   1698         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1699             smlFreeMapItemPtr(pMapItem);
   1700             return rc;
   1701         }
   1702     }
   1703 
   1704     if ((target == 0) || (source == 0)) {
   1705         smlFreeMapItemPtr(pMapItem);
   1706         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1707     }
   1708 
   1709     *ppElem = pMapItem;
   1710 
   1711     return SML_ERR_OK;
   1712 }
   1713 
   1714 #endif
   1715 
   1716 Ret_t
   1717 buildStatus(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem)
   1718 {
   1719     XltDecScannerPtr_t pScanner;
   1720     SmlStatusPtr_t pStatus;
   1721     Ret_t rc;
   1722     Long_t cmd = 0, data = 0, cmdid = 0;
   1723 
   1724     if (*ppElem != NULL)
   1725         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1726 
   1727     pScanner = pDecoder->scanner;
   1728 
   1729     if ((pStatus = (SmlStatusPtr_t)smlLibMalloc(sizeof(SmlStatus_t))) == NULL)
   1730         return SML_ERR_NOT_ENOUGH_SPACE;
   1731     smlLibMemset(pStatus, 0, sizeof(SmlStatus_t));
   1732 
   1733     /* initialize the element type field */
   1734     pStatus->elementType = SML_PE_STATUS;
   1735 
   1736     if (IS_EMPTY(pScanner->curtok)) {
   1737         smlLibFree(pStatus);
   1738         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1739     }
   1740 
   1741     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1742         smlLibFree(pStatus);
   1743         return rc;
   1744     }
   1745 
   1746     while (pScanner->curtok->type != TOK_TAG_END) {
   1747         switch (pScanner->curtok->tagid) {
   1748 
   1749             /* PCData elements */
   1750             case TN_CMDID:
   1751                 rc = buildPCData(pDecoder, (VoidPtr_t)&pStatus->cmdID);
   1752                 cmdid++;
   1753                 break;
   1754             case TN_MSGREF:
   1755                 rc = buildPCData(pDecoder, (VoidPtr_t)&pStatus->msgRef);
   1756                 break;
   1757             case TN_CMDREF:
   1758                 rc = buildPCData(pDecoder, (VoidPtr_t)&pStatus->cmdRef);
   1759                 break;
   1760             case TN_CMD:
   1761                 rc = buildPCData(pDecoder, (VoidPtr_t)&pStatus->cmd);
   1762                 cmd++;
   1763                 break;
   1764             case TN_DATA:
   1765                 rc = buildPCData(pDecoder, (VoidPtr_t)&pStatus->data);
   1766                 data++;
   1767                 break;
   1768             case TN_CHAL:
   1769                 rc = buildChal(pDecoder, (VoidPtr_t)&pStatus->chal);
   1770                 break;
   1771             case TN_CRED:
   1772                 rc = buildCred(pDecoder, (VoidPtr_t)&pStatus->cred);
   1773                 break;
   1774 
   1775             /* Lists */
   1776             case TN_ITEM:
   1777                 rc = appendItemList(pDecoder, (VoidPtr_t)&pStatus->itemList);
   1778                 break;
   1779             case TN_TARGETREF:
   1780                 rc = appendTargetRefList(pDecoder, (VoidPtr_t)&pStatus->targetRefList);
   1781                 break;
   1782             case TN_SOURCEREF:
   1783                 rc = appendSourceRefList(pDecoder, (VoidPtr_t)&pStatus->sourceRefList);
   1784                 break;
   1785 
   1786             default:
   1787                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1788         }
   1789         if (rc != SML_ERR_OK) {
   1790             smlFreeStatus(pStatus);
   1791             return rc;
   1792         }
   1793         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1794             smlFreeStatus(pStatus);
   1795             return rc;
   1796         }
   1797     }
   1798 
   1799     if ((cmd == 0) || (data == 0) || (cmdid == 0))
   1800     {
   1801         smlFreeStatus(pStatus);
   1802         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1803     }
   1804 
   1805     *ppElem = pStatus;
   1806 
   1807     return SML_ERR_OK;
   1808 }
   1809 
   1810 #ifdef RESULT_RECEIVE
   1811 Ret_t
   1812 buildResults(XltDecoderPtr_t pDecoder, VoidPtr_t *ppResults)
   1813 {
   1814     XltDecScannerPtr_t pScanner;
   1815     SmlResultsPtr_t pResults;
   1816     Ret_t rc;
   1817     Long_t cmdref = 0, items = 0, cmdid = 0;
   1818 
   1819     if (*ppResults != NULL)
   1820         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1821 
   1822     pScanner = pDecoder->scanner;
   1823 
   1824     if ((pResults = (SmlResultsPtr_t)smlLibMalloc(sizeof(SmlResults_t))) == NULL)
   1825         return SML_ERR_NOT_ENOUGH_SPACE;
   1826     smlLibMemset(pResults, 0, sizeof(SmlResults_t));
   1827 
   1828     /* initialize the element type field */
   1829     pResults->elementType = SML_PE_RESULTS;
   1830 
   1831     if (IS_EMPTY(pScanner->curtok)) {
   1832         smlLibFree(pResults);
   1833         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1834     }
   1835 
   1836     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1837         smlLibFree(pResults);
   1838         return rc;
   1839     }
   1840 
   1841     while (pScanner->curtok->type != TOK_TAG_END) {
   1842         switch (pScanner->curtok->tagid) {
   1843 
   1844             /* PCDATA elements */
   1845             case TN_CMDID:
   1846                 rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->cmdID);
   1847                 cmdid++;
   1848                 break;
   1849             case TN_MSGREF:
   1850                 rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->msgRef);
   1851                 break;
   1852             case TN_CMDREF:
   1853                 rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->cmdRef);
   1854                 cmdref++;
   1855                 break;
   1856             case TN_META:
   1857                 rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->meta);
   1858                 break;
   1859             case TN_TARGETREF:
   1860                 rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->targetRef);
   1861                 break;
   1862             case TN_SOURCEREF:
   1863                 rc = buildPCData(pDecoder, (VoidPtr_t)&pResults->sourceRef);
   1864                 break;
   1865 
   1866                 /* Lists */
   1867             case TN_ITEM:
   1868                 rc = appendItemList(pDecoder, &pResults->itemList);
   1869                 items++;
   1870                 break;
   1871 
   1872             default:
   1873                 rc = SML_ERR_XLT_INVAL_SYNCML_DOC;
   1874         }
   1875         if (rc != SML_ERR_OK) {
   1876             smlFreeResults(pResults);
   1877             return rc;
   1878         }
   1879         if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1880             smlFreeResults(pResults);
   1881             return rc;
   1882         }
   1883     }
   1884 
   1885     if ((cmdref == 0) || (items == 0) || (cmdid == 0))
   1886     {
   1887         smlFreeResults(pResults);
   1888         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1889     }
   1890 
   1891     *ppResults = pResults;
   1892 
   1893     return SML_ERR_OK;
   1894 }
   1895 
   1896 #endif
   1897 
   1898 Ret_t
   1899 buildPCData(XltDecoderPtr_t pDecoder, VoidPtr_t *ppPCData)
   1900 {
   1901     XltDecScannerPtr_t pScanner;
   1902     SmlPcdataPtr_t pPCData = 0;
   1903     SmlPcdataExtension_t ext;
   1904     Ret_t rc;
   1905 
   1906     pScanner = pDecoder->scanner;
   1907 
   1908     if (*ppPCData != NULL)
   1909         return SML_ERR_XLT_INVAL_SYNCML_DOC;
   1910 
   1911     if (IS_EMPTY(pScanner->curtok)) {
   1912         if ((pPCData = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL)
   1913             return SML_ERR_NOT_ENOUGH_SPACE;
   1914 
   1915         smlLibMemset(pPCData, 0, sizeof(SmlPcdata_t));
   1916 
   1917         *ppPCData = pPCData;
   1918         return SML_ERR_OK;
   1919     }
   1920 
   1921     pPCData = NULL;
   1922 
   1923     if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1924         if (rc == SML_ERR_XLT_INVAL_SYNCML_DOC) { /* leaks if dtd failed */
   1925 	        pPCData = pScanner->curtok->pcdata;
   1926  		    *ppPCData = pPCData;
   1927  		}
   1928 
   1929         return rc;
   1930     }
   1931 
   1932     if (IS_CONTENT(pScanner->curtok)) {
   1933         /* PCData element has a regular string or opaque content */
   1934         while (pScanner->curtok->type == TOK_CONT) {
   1935             if (pPCData == NULL)
   1936                 pPCData = pScanner->curtok->pcdata;
   1937             else {
   1938                 pPCData = concatPCData(pPCData, pScanner->curtok->pcdata);
   1939                 smlLibFree(pScanner->curtok->pcdata->content);
   1940                 smlLibFree(pScanner->curtok->pcdata);
   1941 
   1942                 if (pPCData == NULL)
   1943                     return SML_ERR_XLT_INVAL_PCDATA;
   1944             }
   1945 
   1946            if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1947                 *ppPCData = pPCData;
   1948                 return rc;
   1949             }
   1950         }
   1951     } else if (IS_START_OR_EMPTY(pScanner->curtok)) {
   1952         /* PCData element contains an XML dokument that is handled by an
   1953            extension mechanism  */
   1954         ext = pScanner->curtok->ext;
   1955         if ((rc = discardToken(pDecoder)) != SML_ERR_OK) return rc;
   1956         if ((pPCData = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL)
   1957             return SML_ERR_NOT_ENOUGH_SPACE;
   1958         smlLibMemset(pPCData, 0, sizeof(SmlPcdata_t));
   1959         pPCData->contentType = SML_PCDATA_EXTENSION;
   1960         pPCData->extension = ext;
   1961         switch (ext) {
   1962 #ifdef __USE_METINF__
   1963 				case SML_EXT_METINF:
   1964 
   1965                         if ((rc = buildMetInfMetInfCmd(pDecoder, (VoidPtr_t)&pPCData->content)) != SML_ERR_OK) {
   1966                         smlLibFree(pPCData);
   1967                         return rc;
   1968                     }
   1969                 break;
   1970 #endif
   1971 #ifdef __USE_DEVINF__
   1972 				case SML_EXT_DEVINF:
   1973 
   1974 				if ((rc = buildDevInfDevInfCmd(pDecoder, (VoidPtr_t)&pPCData->content)) != SML_ERR_OK) {
   1975 
   1976 					smlLibFree(pPCData);
   1977                         return rc;
   1978                     }
   1979 
   1980                 /* the scanner must point to the closing PCDATA tag */
   1981                 if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1982                     smlLibFree(pPCData);
   1983                     return rc;
   1984                 }
   1985                 break;
   1986 #endif
   1987 #ifdef __USE_DMTND__
   1988             case SML_EXT_DMTND:
   1989 
   1990 				if ((rc = buildDmTndCmd(pDecoder, (VoidPtr_t)&pPCData->content)) != SML_ERR_OK) {
   1991 
   1992 					smlLibFree(pPCData);
   1993                     return rc;
   1994                 }
   1995 
   1996                 /* the scanner must point to the closing PCDATA tag */
   1997                 if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) {
   1998                     smlLibFree(pPCData);
   1999                     return rc;
   2000                 }
   2001                 break;
   2002 #endif
   2003             default:
   2004                 smlFreePcdata(pPCData);
   2005                 return SML_ERR_XLT_INVAL_EXT;
   2006         }
   2007 
   2008     } else if (IS_END(pScanner->curtok)) {
   2009         /* PCData element is empty */
   2010     } else {
   2011         return SML_ERR_XLT_INVAL_PCDATA;
   2012     }
   2013 
   2014 
   2015     if (pScanner->curtok->type != TOK_TAG_END)
   2016         return SML_ERR_XLT_INVAL_PCDATA;
   2017 
   2018     if (pPCData == NULL) {
   2019         if ((pPCData = (SmlPcdataPtr_t)smlLibMalloc(sizeof(SmlPcdata_t))) == NULL)
   2020             return SML_ERR_NOT_ENOUGH_SPACE;
   2021         smlLibMemset(pPCData, 0, sizeof(SmlPcdata_t));
   2022     }
   2023 
   2024     *ppPCData = pPCData;
   2025 
   2026     return SML_ERR_OK;
   2027 }
   2028 
   2029 Ret_t
   2030 buildPCDataList(XltDecoderPtr_t pDecoder, VoidPtr_t *ppPCData)
   2031 {
   2032 		SmlPcdataListPtr_t pPCDataList = NULL, pPrev = NULL;
   2033 
   2034 		pPCDataList = (SmlPcdataListPtr_t) *ppPCData;
   2035 
   2036 		/* advance to the end of the list, and create ther an empty list element */
   2037 		while (pPCDataList != NULL) {
   2038 			pPrev = pPCDataList;
   2039 			pPCDataList = pPrev->next;
   2040 		}
   2041 		if ((pPCDataList = (SmlPcdataListPtr_t)smlLibMalloc(sizeof(SmlPcdataList_t))) == NULL)
   2042           return SML_ERR_NOT_ENOUGH_SPACE;
   2043         smlLibMemset(pPCDataList, 0, sizeof(SmlPcdataList_t));
   2044 		if (pPrev != NULL) /* we already had some entries in the list */
   2045 			pPrev->next = pPCDataList;
   2046 		else /* nope we created a new list */
   2047 			*ppPCData = pPCDataList;
   2048 		pPCDataList->data = NULL;
   2049 		/* at this point pPCDataList should point to an valid list element */
   2050 		return buildPCData(pDecoder, (VoidPtr_t)&pPCDataList->data);
   2051 }
   2052 
   2053 
   2054 static Ret_t
   2055 appendItemList(XltDecoderPtr_t pDecoder, SmlItemListPtr_t *ppItemList)
   2056 {
   2057     SmlItemListPtr_t pNewItemList;
   2058     SmlItemListPtr_t pItemList;
   2059     Ret_t rc;
   2060 
   2061     pItemList = *ppItemList;
   2062     if (pItemList != NULL)
   2063         while (pItemList->next != NULL)
   2064             pItemList = pItemList->next;
   2065 
   2066     if ((pNewItemList = (SmlItemListPtr_t)smlLibMalloc(sizeof(SmlItemList_t))) == NULL)
   2067         return SML_ERR_NOT_ENOUGH_SPACE;
   2068     smlLibMemset(pNewItemList, 0, sizeof(SmlItemList_t));
   2069 
   2070     if ((rc = buildItem(pDecoder, (VoidPtr_t)&pNewItemList->item)) != SML_ERR_OK) {
   2071         smlLibFree(pNewItemList);
   2072         return rc;
   2073     }
   2074 
   2075     if (pItemList == NULL)
   2076         *ppItemList = pNewItemList;
   2077     else
   2078         pItemList->next = pNewItemList;
   2079 
   2080     return SML_ERR_OK;
   2081 }
   2082 
   2083 static Ret_t
   2084 appendSourceList(XltDecoderPtr_t pDecoder, SmlSourceListPtr_t *ppSourceList)
   2085 {
   2086     SmlSourceListPtr_t pNewSourceList;
   2087     SmlSourceListPtr_t pSourceList;
   2088     Ret_t rc;
   2089 
   2090     pSourceList = *ppSourceList;
   2091     if (pSourceList != NULL)
   2092         while (pSourceList->next != NULL)
   2093             pSourceList = pSourceList->next;
   2094 
   2095     if ((pNewSourceList = (SmlSourceListPtr_t)smlLibMalloc(sizeof(SmlSourceList_t))) == NULL)
   2096         return SML_ERR_NOT_ENOUGH_SPACE;
   2097     smlLibMemset(pNewSourceList, 0, sizeof(SmlSourceList_t));
   2098 
   2099     if ((rc = buildTargetOrSource(pDecoder, (VoidPtr_t)&pNewSourceList->source)) != SML_ERR_OK) {
   2100         smlLibFree(pNewSourceList);
   2101         return rc;
   2102     }
   2103 
   2104     if (pSourceList == NULL)
   2105         *ppSourceList = pNewSourceList;
   2106     else
   2107         pSourceList->next = pNewSourceList;
   2108 
   2109     return SML_ERR_OK;
   2110 }
   2111 
   2112 #ifdef MAPITEM_RECEIVE
   2113 
   2114 static Ret_t
   2115 appendMapItemList(XltDecoderPtr_t pDecoder, SmlMapItemListPtr_t *ppMapItemList)
   2116 {
   2117     SmlMapItemListPtr_t pNewMapItemList;
   2118     SmlMapItemListPtr_t pMapItemList;
   2119     Ret_t rc;
   2120 
   2121     pMapItemList = *ppMapItemList;
   2122     if (pMapItemList != NULL)
   2123         while (pMapItemList->next != NULL)
   2124             pMapItemList = pMapItemList->next;
   2125 
   2126     if ((pNewMapItemList = (SmlMapItemListPtr_t)smlLibMalloc(sizeof(SmlMapItemList_t))) == NULL)
   2127         return SML_ERR_NOT_ENOUGH_SPACE;
   2128     smlLibMemset(pNewMapItemList, 0, sizeof(SmlMapItemList_t));
   2129 
   2130     if ((rc = buildMapItem(pDecoder, (VoidPtr_t)&pNewMapItemList->mapItem)) != SML_ERR_OK) {
   2131         smlLibFree(pNewMapItemList);
   2132         return rc;
   2133     }
   2134 
   2135     if (pMapItemList == NULL)
   2136         *ppMapItemList = pNewMapItemList;
   2137     else
   2138         pMapItemList->next = pNewMapItemList;
   2139 
   2140     return SML_ERR_OK;
   2141 }
   2142 #endif
   2143 
   2144 static Ret_t
   2145 appendTargetRefList(XltDecoderPtr_t pDecoder, SmlTargetRefListPtr_t *ppTargetRefList)
   2146 {
   2147     SmlTargetRefListPtr_t pNewTargetRefList;
   2148     SmlTargetRefListPtr_t pTargetRefList;
   2149     Ret_t rc;
   2150 
   2151     pTargetRefList = *ppTargetRefList;
   2152     if (pTargetRefList != NULL)
   2153         while (pTargetRefList->next != NULL)
   2154             pTargetRefList = pTargetRefList->next;
   2155 
   2156     if ((pNewTargetRefList = (SmlTargetRefListPtr_t)smlLibMalloc(sizeof(SmlTargetRefList_t))) == NULL)
   2157         return SML_ERR_NOT_ENOUGH_SPACE;
   2158     smlLibMemset(pNewTargetRefList, 0, sizeof(SmlTargetRefList_t));
   2159 
   2160     if ((rc = buildPCData(pDecoder, (VoidPtr_t)&pNewTargetRefList->targetRef)) != SML_ERR_OK) {
   2161         smlFreePcdata(pNewTargetRefList->targetRef);
   2162         smlLibFree(pNewTargetRefList);
   2163         return rc;
   2164     }
   2165 
   2166     if (pTargetRefList == NULL)
   2167         *ppTargetRefList = pNewTargetRefList;
   2168     else
   2169         pTargetRefList->next = pNewTargetRefList;
   2170 
   2171     return SML_ERR_OK;
   2172 }
   2173 
   2174 static Ret_t
   2175 appendSourceRefList(XltDecoderPtr_t pDecoder, SmlSourceRefListPtr_t *ppSourceRefList)
   2176 {
   2177     SmlSourceRefListPtr_t pNewSourceRefList;
   2178     SmlSourceRefListPtr_t pSourceRefList;
   2179     Ret_t rc;
   2180 
   2181     pSourceRefList = *ppSourceRefList;
   2182     if (pSourceRefList != NULL)
   2183         while (pSourceRefList->next != NULL)
   2184             pSourceRefList = pSourceRefList->next;
   2185 
   2186     if ((pNewSourceRefList = (SmlSourceRefListPtr_t)smlLibMalloc(sizeof(SmlSourceRefList_t))) == NULL)
   2187         return SML_ERR_NOT_ENOUGH_SPACE;
   2188     smlLibMemset(pNewSourceRefList, 0, sizeof(SmlSourceRefList_t));
   2189 
   2190     if ((rc = buildPCData(pDecoder, (VoidPtr_t)&pNewSourceRefList->sourceRef)) != SML_ERR_OK) {
   2191         smlFreePcdata(pNewSourceRefList->sourceRef);
   2192         smlLibFree(pNewSourceRefList);
   2193         return rc;
   2194     }
   2195 
   2196     if (pSourceRefList == NULL)
   2197         *ppSourceRefList = pNewSourceRefList;
   2198     else
   2199         pSourceRefList->next = pNewSourceRefList;
   2200 
   2201     return SML_ERR_OK;
   2202 }
   2203 
   2204