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