📄 xltdecxml.c
字号:
/*************************************************************************//* module: XML scanner *//* file: XLTDecXml.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 XML scanner/tokenizer. Used by the SyncML parser. */#include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++#include <define.h>#ifdef __SML_XML__/*************************************************************************//* Definitions *//*************************************************************************/#include "xltdeccom.h"#include "xlttags.h"#include <libmem.h>#include <libstr.h>#include <smlerr.h>/** * Private Interface for the XML scanner. */typedef struct xmlScannerPriv_s xmlScannerPriv_t, *xmlScannerPrivPtr_t;struct xmlScannerPriv_s{ /* public */ Ret_t (*nextTok)(XltDecScannerPtr_t); Ret_t (*destroy)(XltDecScannerPtr_t); Ret_t (*pushTok)(XltDecScannerPtr_t); void (*setBuf)(XltDecScannerPtr_t pScanner, const MemPtr_t pBufStart, const MemPtr_t pBufEnd); MemPtr_t (*getPos)(XltDecScannerPtr_t pScanner); XltDecTokenPtr_t curtok; /* current token */ Long_t charset; /* 0 */ String_t charsetStr; /* character set */ Long_t pubID; /* 0 */ String_t pubIDStr; /* document public identifier */ SmlPcdataExtension_t ext; /* which is the actual open namespace ? */ SmlPcdataExtension_t prev_ext; /* which is the previous open namespace ? */ XltTagID_t ext_tag; /* which tag started the actual namespace ? */ XltTagID_t prev_ext_tag; /* which tag started the previous open namespace ? */ String_t nsprefix; /* prefix used for active namespace (if any) */ Byte_t nsprelen; /* how long is the prefix ? (to save smlLibStrlen calls) */ Flag_t finished; /* private */ MemPtr_t pos; /* current position */ MemPtr_t bufend; /* end of buffer */};/** * Public methods of the scanner interface. * * Description see XLTDecCom.h. */static Ret_t _destroy(XltDecScannerPtr_t);static Ret_t _nextTok(XltDecScannerPtr_t);static Ret_t _pushTok(XltDecScannerPtr_t);static void _setBuf(XltDecScannerPtr_t, const MemPtr_t, const MemPtr_t); static MemPtr_t _getPos(XltDecScannerPtr_t); /** * FUNCTION: readBytes * * Advance the current position pointer after checking whether the end of * the buffer has been reached. If the end of the buffer has been reached * the scanner's finished flag is set. * * PRE-Condition: * POST-Condition: * * IN: bytes, read this many bytes * * IN/OUT: pScanner, the scanner * * RETURNS: 1, if end of buffer has not been reached * 0 otherwise */static Boolean_t readBytes(xmlScannerPrivPtr_t pScanner, Long_t bytes);/** * Skip whitespaces. */static void skipS(xmlScannerPrivPtr_t pScanner);static Ret_t xmlTag(xmlScannerPrivPtr_t pScanner, Byte_t endtag);static Ret_t xmlName(xmlScannerPrivPtr_t pScanner, String_t *name);static Ret_t xmlCharData(xmlScannerPrivPtr_t pScanner);static Ret_t xmlProlog(xmlScannerPrivPtr_t pScanner);static Ret_t xmlDocTypeDecl(xmlScannerPrivPtr_t pScanner);static Ret_t xmlXMLDecl(xmlScannerPrivPtr_t pScanner);static Ret_t xmlAttribute(xmlScannerPrivPtr_t pScanner, String_t *name, String_t *value);static Ret_t xmlStringConst(xmlScannerPrivPtr_t pScanner, String_t *value);static Ret_t xmlSkipPCDATA(xmlScannerPrivPtr_t pScanner);static Ret_t xmlSkipComment(xmlScannerPrivPtr_t pScanner);static Ret_t xmlSkipAttributes(xmlScannerPrivPtr_t pScanner);static Ret_t xmlSkipPI(xmlScannerPrivPtr_t pScanner);static Ret_t xmlCDATA(xmlScannerPrivPtr_t pScanner);Boolean_t isPcdata(XltTagID_t tagid);/*************************************************************************//* External Functions *//*************************************************************************/Ret_txltDecXmlInit(const MemPtr_t pBufEnd, MemPtr_t *ppBufStart, XltDecScannerPtr_t *ppScanner){ xmlScannerPrivPtr_t pScanner; Ret_t rc; pScanner = (xmlScannerPrivPtr_t)smlLibMalloc(sizeof(xmlScannerPriv_t)); if (pScanner == NULL) { *ppScanner = NULL; return SML_ERR_NOT_ENOUGH_SPACE; } pScanner->finished = 0; pScanner->pos = *ppBufStart; pScanner->bufend = pBufEnd; pScanner->curtok = (XltDecTokenPtr_t)smlLibMalloc(sizeof(XltDecToken_t)); if (pScanner->curtok == NULL) { smlLibFree(pScanner); *ppScanner = NULL; return SML_ERR_NOT_ENOUGH_SPACE; } pScanner->curtok->pcdata = NULL; pScanner->curtok->tagid = TN_UNDEF; pScanner->pubID = 0; pScanner->pubIDStr = NULL; pScanner->charset = 0; pScanner->charsetStr = NULL; pScanner->ext = SML_EXT_UNDEFINED; pScanner->prev_ext = (SmlPcdataExtension_t)255; pScanner->ext_tag = TN_UNDEF; pScanner->prev_ext_tag = TN_UNDEF; pScanner->nsprelen = 0; pScanner->nsprefix = NULL; /* point public/private methods to the right implementation */ pScanner->nextTok = _nextTok; pScanner->destroy = _destroy; pScanner->pushTok = _pushTok; pScanner->setBuf = _setBuf; pScanner->getPos = _getPos; if ((rc = xmlProlog(pScanner)) != SML_ERR_OK) { smlLibFree(pScanner->curtok); smlLibFree(pScanner); *ppScanner = NULL; return rc; } *ppScanner = (XltDecScannerPtr_t)pScanner; return SML_ERR_OK;}/** * FUNCTION: destroy * * Free memory. Description see XltDecAll.h. */static Ret_t_destroy(XltDecScannerPtr_t pScanner){ xmlScannerPrivPtr_t pScannerPriv; if (pScanner == NULL) return SML_ERR_OK; pScannerPriv = (xmlScannerPrivPtr_t)pScanner; smlLibFree(pScannerPriv->curtok); smlLibFree(pScannerPriv->charsetStr); smlLibFree(pScannerPriv->pubIDStr); smlLibFree(pScannerPriv); return SML_ERR_OK;}/** * FUNCTION: nextTok * * Get next token. Description see XltDecAll.h. */static Ret_t_nextTok(XltDecScannerPtr_t pScanner){ xmlScannerPrivPtr_t pScannerPriv; Ret_t rc; pScannerPriv = (xmlScannerPrivPtr_t)pScanner; pScannerPriv->curtok->start = pScannerPriv->pos; skipS(pScannerPriv); /* skip unsupported elements until we find a supported one */ rc = 0; while (!rc) { if (smlLibStrncmp((String_t)pScannerPriv->pos, "<!--", 4) == 0) { rc = xmlSkipComment(pScannerPriv); } else if (smlLibStrncmp((String_t)pScannerPriv->pos, "<?", 2) == 0) { rc = xmlSkipPI(pScannerPriv); } else if (smlLibStrncmp((String_t)pScannerPriv->pos, "</", 2) == 0) { rc = xmlTag(pScannerPriv, 1); break; } else if (smlLibStrncmp((String_t)pScannerPriv->pos, "<![CDATA[", 9) == 0) { rc = xmlCDATA(pScannerPriv); break; } else if ((isPcdata(pScannerPriv->curtok->tagid)) && (pScannerPriv->curtok->type != TOK_TAG_END)) { rc = xmlSkipPCDATA(pScannerPriv); break; } else if (smlLibStrncmp((String_t)pScannerPriv->pos, "<", 1) == 0) { rc = xmlTag(pScannerPriv, 0); break; } else { rc = xmlCharData(pScannerPriv); break; } } if (rc) return rc; return SML_ERR_OK;}/** * FUNCTION: pushTok * * Reset the scanner to the starting position of the current token within * the buffer. Description see XltDecAll.h. */static Ret_t _pushTok(XltDecScannerPtr_t pScanner){ xmlScannerPrivPtr_t pScannerPriv; pScannerPriv = (xmlScannerPrivPtr_t)pScanner; pScannerPriv->pos = pScannerPriv->curtok->start; /* invalidate curtok */ /* T.K. Possible Error. pScannerPriv->curtok is of type XltDecToken_t NOT ...Ptr_t */ // OrigLine: // smlLibMemset(pScannerPriv->curtok, 0, sizeof(XltDecTokenPtr_t)); pScannerPriv->curtok->type = (XltTokType_t)0; return SML_ERR_OK;}/** * FUNCTION: setBuf * * Set the working buffer of the scanner. */static void_setBuf(XltDecScannerPtr_t pScanner, const MemPtr_t pBufStart, const MemPtr_t pBufEnd){ xmlScannerPrivPtr_t pScannerPriv = (xmlScannerPrivPtr_t)pScanner; pScannerPriv->pos = pBufStart; pScannerPriv->bufend = pBufEnd;}/** * FUNCTION: getPos * * Get the current position of the scanner within its working buffer. */static MemPtr_t_getPos(XltDecScannerPtr_t pScanner){ return ((xmlScannerPrivPtr_t)pScanner)->pos;}/*************************************************************************//* Internal Functions *//*************************************************************************//** * FUNCTION: readBytes * * Advance the position pointer. Description see above. */static Boolean_treadBytes(xmlScannerPrivPtr_t pScanner, Long_t bytes){ if (pScanner->pos + bytes > pScanner->bufend) { pScanner->finished = 1; return 0; } pScanner->pos += bytes; return 1;}/** * FUNCTION: skipS * * Skip whitespace. */static void skipS(xmlScannerPrivPtr_t pScanner){ for (;;) { switch (*pScanner->pos) { case 9: /* tab stop */ case 10: /* line feed */ case 13: /* carriage return */ case 32: /* space */ // %%% luz: 2001-07-03: added exit from loop if no more bytes if (!readBytes(pScanner, 1)) return; break; default: return; } }}/** * FUNCTION: xmlProlog * * Scan the XML prolog (might be empty...). */static Ret_txmlProlog(xmlScannerPrivPtr_t pScanner){ Ret_t rc; if (pScanner->pos + 5 > pScanner->bufend) return SML_ERR_OK; if (smlLibStrncmp((String_t)pScanner->pos, "<?xml", 5) == 0) if ((rc = xmlXMLDecl(pScanner)) != SML_ERR_OK) return rc; skipS(pScanner); while ((pScanner->pos + 4 <= pScanner->bufend) && ((smlLibStrncmp((String_t)pScanner->pos, "<!--", 4) == 0) || (smlLibStrncmp((String_t)pScanner->pos, "<?", 2) == 0))) { if (smlLibStrncmp((String_t)pScanner->pos, "<!--", 4) == 0) rc = xmlSkipComment(pScanner); else rc = xmlSkipPI(pScanner); if (rc != SML_ERR_OK) return rc; skipS(pScanner); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -