📄 xltdec.c
字号:
/*************************************************************************//* module: SyncmML Decoder *//* file: XLTDec.c *//* target system: all *//* target OS: all *//*************************************************************************//* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * *//** * The SyncML parser. *//*************************************************************************//* Definitions *//*************************************************************************/#include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++#include "xltdec.h"#include "xltdeccom.h"#include "xlttags.h"#include "xltutilstack.h"#include "xlttagtbl.h"#include "xltmetinf.h"#include "xltdevinf.h"#include <smldef.h>#include <smldtd.h>#include <smlmetinfdtd.h>#include <smldevinfdtd.h>#include <smlerr.h>#include <libmem.h>#include <libstr.h>#include <mgrutil.h>#ifdef __USE_EXTENSIONS__/* prototype for function in xltdecwbxml.c */void subdtdDecodeWbxml(XltDecoderPtr_t pDecoder,SmlPcdataPtr_t *ppPcdata);#endif/** * FUNCTION: concatPCData * * Tries to concatenate two Pcdata elements. Only works when the two * elements are of the same type (e.g. SML_PCDATA_STRING). Returns a * pointer to the new Pcdata element or NULL if concatenation failed. */static SmlPcdataPtr_t concatPCData(SmlPcdataPtr_t pDat1, const SmlPcdataPtr_t pDat2);/** * FUNCTION: appendXXXList * * These are auxiliary functions for building SyncML elements that contain * lists of certain other data structures (e.g. Items). They take an * existing list (e.g. of type ItemListPtr_t) and append an appropriate * element at the end. If the ListPtr points to NULL a new list is created. * * PRE-Condition: * The scanner's current token is the start tag (may be * empty) of the SyncML element to be appended to the list. * * POST-Condition: * The scanner's current token is the end tag (or empty * start tag) of the SyncML element that was added to the * list. * * IN/OUT: pDecoder, the decoder * ppXXXList, NULL or an initialized list, to which element * will be appended * * RETURNS: SML_ERR_OK, if an element was successfully appended * else error code */static Ret_t appendItemList(XltDecoderPtr_t pDecoder, SmlItemListPtr_t *ppItemList);static Ret_t appendSourceList(XltDecoderPtr_t pDecoder, SmlSourceListPtr_t *ppSourceList);#ifdef MAPITEM_RECEIVE static Ret_t appendMapItemList(XltDecoderPtr_t pDecoder, SmlMapItemListPtr_t *ppMapItemList);#endifstatic Ret_t appendTargetRefList(XltDecoderPtr_t pDecoder, SmlTargetRefListPtr_t *ppTargetRefList);static Ret_t appendSourceRefList(XltDecoderPtr_t pDecoder, SmlSourceRefListPtr_t *ppSourceRefList);/* if the commands are not defined we let the functions point to NULL */#ifndef RESULT_RECEIVE#define buildResults NULL#endif#ifndef MAP_RECEIVE#define buildMap NULL#endif#ifndef EXEC_RECEIVE#define buildExec NULL#endif#if !defined(ATOM_RECEIVE) && !defined(SEQUENCE_RECEIVE)#define buildAtomOrSeq NULL#endif#ifndef SEARCH_RECEIVE#define buildSearch NULL#endiftypedef struct PEBuilder_s{ XltTagID_t tagid; SmlProtoElement_t type; Ret_t (*build)(XltDecoderPtr_t pDecoder, VoidPtr_t *ppElem);} PEBuilder_t, *PEBuilderPtr_t;PEBuilderPtr_t getPETable(void);PEBuilderPtr_t getPETable(void){ PEBuilderPtr_t _tmpPEPtr; PEBuilder_t PE[] = { { TN_ADD, SML_PE_ADD, buildGenericCmd }, { TN_ALERT, SML_PE_ALERT, buildAlert }, { TN_ATOMIC, SML_PE_ATOMIC_START, buildAtomOrSeq }, { TN_COPY, SML_PE_COPY, buildGenericCmd }, { TN_DELETE, SML_PE_DELETE, buildGenericCmd }, { TN_EXEC, SML_PE_EXEC, buildExec }, { TN_GET, SML_PE_GET, buildPutOrGet }, { TN_MAP, SML_PE_MAP, buildMap }, { TN_PUT, SML_PE_PUT, buildPutOrGet }, { TN_RESULTS, SML_PE_RESULTS, buildResults }, { TN_SEARCH, SML_PE_SEARCH, buildSearch }, { TN_SEQUENCE, SML_PE_SEQUENCE_START, buildAtomOrSeq }, { TN_STATUS, SML_PE_STATUS, buildStatus }, { TN_SYNC, SML_PE_SYNC_START, buildSync }, { TN_REPLACE, SML_PE_REPLACE, buildGenericCmd }, { TN_UNDEF, SML_PE_UNDEF, 0 } }; _tmpPEPtr = smlLibMalloc(sizeof(PE)); if (_tmpPEPtr == NULL) return NULL; smlLibMemcpy(_tmpPEPtr, &PE, sizeof(PE)); return _tmpPEPtr; }/*************************************************************************//* External Functions *//*************************************************************************//** * Description see XLTDec.h header file. */Ret_txltDecInit(const SmlEncoding_t enc, const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, XltDecoderPtr_t *ppDecoder, SmlSyncHdrPtr_t *ppSyncHdr){ XltDecoderPtr_t pDecoder; Ret_t rc; /* create new decoder object */ if ((pDecoder = (XltDecoderPtr_t)smlLibMalloc(sizeof(XltDecoder_t))) == NULL) return SML_ERR_NOT_ENOUGH_SPACE; pDecoder->finished = 0; pDecoder->final = 0; pDecoder->scanner = NULL; if ((rc = xltUtilCreateStack(&pDecoder->tagstack, 10)) != SML_ERR_OK) { xltDecTerminate(pDecoder); return rc; }#ifdef __SML_WBXML__ if (enc == SML_WBXML) { rc = xltDecWbxmlInit(pBufEnd, ppBufPos, &pDecoder->scanner); if (rc == SML_ERR_OK) { pDecoder->charset = pDecoder->scanner->charset; pDecoder->charsetStr = NULL; } } else#endif#ifdef __SML_XML__ if (enc == SML_XML) { rc = xltDecXmlInit(pBufEnd, ppBufPos, &pDecoder->scanner); if (rc == SML_ERR_OK) { pDecoder->charset = 0; pDecoder->charsetStr = pDecoder->scanner->charsetStr; } } else#endif { rc = SML_ERR_XLT_ENC_UNK; } if (rc != SML_ERR_OK) { xltDecTerminate((XltDecoderPtr_t)pDecoder); return rc; } /* try to find SyncHdr element, first comes the SyncML tag... */ if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { xltDecTerminate((XltDecoderPtr_t)pDecoder); return rc; } if (!IS_START(pDecoder->scanner->curtok) || (pDecoder->scanner->curtok->tagid != TN_SYNCML)) { smlFreePcdata(pDecoder->scanner->curtok->pcdata); xltDecTerminate((XltDecoderPtr_t)pDecoder); return SML_ERR_XLT_INVAL_SYNCML_DOC; } /* ... then the SyncHdr */ if (((rc = nextToken(pDecoder)) != SML_ERR_OK)) { xltDecTerminate((XltDecoderPtr_t)pDecoder); return rc; } if ((rc = buildSyncHdr(pDecoder, (VoidPtr_t)ppSyncHdr)) != SML_ERR_OK) { xltDecTerminate((XltDecoderPtr_t)pDecoder); return rc; } *ppBufPos = pDecoder->scanner->getPos(pDecoder->scanner); *ppDecoder = (XltDecoderPtr_t)pDecoder; return SML_ERR_OK;}/** * Description see XLTDec.h header file. */Ret_txltDecNext(XltDecoderPtr_t pDecoder, const MemPtr_t pBufEnd, MemPtr_t *ppBufPos, SmlProtoElement_t *pe, VoidPtr_t *ppContent){ XltDecoderPtr_t pDecPriv = (XltDecoderPtr_t)pDecoder; XltDecScannerPtr_t pScanner = pDecPriv->scanner; XltTagID_t tagid; Ret_t rc; int i; pScanner->setBuf(pScanner, *ppBufPos, pBufEnd); /* if we are still outside the SyncBody, look for SyncBody start tag */ if ((rc = pDecPriv->tagstack->top(pDecPriv->tagstack, &tagid)) != SML_ERR_OK) return rc; if (tagid == TN_SYNCML) { if (((rc = nextToken(pDecPriv)) != SML_ERR_OK)) { return rc; } if (!((IS_START(pScanner->curtok)) && (pScanner->curtok->tagid == TN_SYNCBODY))) { return SML_ERR_XLT_INVAL_PROTO_ELEM; } } if ((rc = nextToken(pDecPriv)) != SML_ERR_OK) return rc; /* if we find a SyncML protocol element build the corresponding data structure */ if ((IS_START_OR_EMPTY(pScanner->curtok)) && (pScanner->curtok->tagid != TN_FINAL)) { PEBuilderPtr_t pPEs = getPETable(); if (pPEs == NULL) { smlLibFree(pPEs); return SML_ERR_NOT_ENOUGH_SPACE; } i = 0; while (((pPEs+i)->tagid) != TN_UNDEF) { if (((pPEs+i)->tagid) == pScanner->curtok->tagid) { *pe = ((pPEs+i)->type); if ((rc = (pPEs+i)->build(pDecPriv, ppContent)) != SML_ERR_OK) { smlLibFree(pPEs); return rc; } /* T.K. adjust the SML_PE_ for 'generic' structures */ if (*pe == SML_PE_GENERIC) { SmlGenericCmdPtr_t g = *ppContent; switch ((int) ((pPEs+i)->tagid)) { case TN_ADD : g->elementType = SML_PE_ADD; break; case TN_COPY : g->elementType = SML_PE_COPY; break; case TN_DELETE : g->elementType = SML_PE_DELETE; break; case TN_REPLACE: g->elementType = SML_PE_REPLACE; break; } } break; } i++; } if (((pPEs+i)->tagid) == TN_UNDEF) { *pe = SML_PE_UNDEF; *ppContent = NULL; smlLibFree(pPEs); return SML_ERR_XLT_INVAL_PROTO_ELEM; } smlLibFree(pPEs); } else { /* found end tag */ switch (pScanner->curtok->tagid) { case TN_ATOMIC: *pe = SML_PE_ATOMIC_END; *ppContent = NULL; break; case TN_SEQUENCE: *pe = SML_PE_SEQUENCE_END; *ppContent = NULL; break; case TN_SYNC: *pe = SML_PE_SYNC_END; *ppContent = NULL; break; case TN_FINAL: *pe = SML_PE_FINAL; *ppContent = NULL; pDecPriv->final = 1; break; case TN_SYNCBODY: /* next comes the SyncML end tag, then we're done */ if ((rc = nextToken(pDecPriv)) != SML_ERR_OK) return rc; if ((pScanner->curtok->type == TOK_TAG_END) && (pScanner->curtok->tagid == TN_SYNCML)) { *pe = SML_PE_UNDEF; *ppContent = NULL; pDecPriv->finished = 1; } else { return SML_ERR_XLT_INVAL_SYNCML_DOC; } break; default: return SML_ERR_XLT_INVAL_PROTO_ELEM; } } *ppBufPos = pScanner->getPos(pScanner); return SML_ERR_OK;}/** * Description see XLTDec.h header file. */Ret_txltDecTerminate(XltDecoderPtr_t pDecoder){ XltDecoderPtr_t pDecPriv; if (pDecoder == NULL) return SML_ERR_OK; pDecPriv = (XltDecoderPtr_t)pDecoder; if (pDecPriv->scanner != NULL) pDecPriv->scanner->destroy(pDecPriv->scanner); if (pDecPriv->tagstack != NULL) pDecPriv->tagstack->destroy(pDecPriv->tagstack); smlLibFree(pDecPriv); return SML_ERR_OK;}Ret_t xltDecReset(XltDecoderPtr_t pDecoder){ return xltDecTerminate(pDecoder);}/** * Gets the next token from the scanner. * Checks if the current tag is an end tag and if so, whether the last * open start tag has the same tag id as the current end tag. An open start * tag is one which matching end tag has not been seen yet. * If the current tag is a start tag its tag ID will be pushed onto the * tag stack. * If the current tag is an empty tag or not a tag at all nothing will be * done. */Ret_tnextToken(XltDecoderPtr_t pDecoder){ XltUtilStackPtr_t pTagStack; XltDecTokenPtr_t pToken; Ret_t rc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -