⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 5 页
字号:
    else        ctxt->name = NULL;    ret = ctxt->nameTab[ctxt->nameNr];    ctxt->nameTab[ctxt->nameNr] = NULL;    return (ret);}#endif /* LIBXML_PUSH_ENABLED *//** * namePush: * @ctxt:  an XML parser context * @value:  the element name * * Pushes a new element name on top of the name stack * * Returns -1 in case of error, the index in the stack otherwise */intnamePush(xmlParserCtxtPtr ctxt, const xmlChar * value){    if (ctxt == NULL) return (-1);    if (ctxt->nameNr >= ctxt->nameMax) {        const xmlChar * *tmp;        ctxt->nameMax *= 2;        tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,                                    ctxt->nameMax *                                    sizeof(ctxt->nameTab[0]));        if (tmp == NULL) {	    ctxt->nameMax /= 2;	    goto mem_error;        }	ctxt->nameTab = tmp;    }    ctxt->nameTab[ctxt->nameNr] = value;    ctxt->name = value;    return (ctxt->nameNr++);mem_error:    xmlErrMemory(ctxt, NULL);    return (-1);}/** * namePop: * @ctxt: an XML parser context * * Pops the top element name from the name stack * * Returns the name just removed */const xmlChar *namePop(xmlParserCtxtPtr ctxt){    const xmlChar *ret;    if ((ctxt == NULL) || (ctxt->nameNr <= 0))        return (NULL);    ctxt->nameNr--;    if (ctxt->nameNr > 0)        ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];    else        ctxt->name = NULL;    ret = ctxt->nameTab[ctxt->nameNr];    ctxt->nameTab[ctxt->nameNr] = NULL;    return (ret);}static int spacePush(xmlParserCtxtPtr ctxt, int val) {    if (ctxt->spaceNr >= ctxt->spaceMax) {	ctxt->spaceMax *= 2;        ctxt->spaceTab = (int *) xmlRealloc(ctxt->spaceTab,	             ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));        if (ctxt->spaceTab == NULL) {	    xmlErrMemory(ctxt, NULL);	    return(0);	}    }    ctxt->spaceTab[ctxt->spaceNr] = val;    ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];    return(ctxt->spaceNr++);}static int spacePop(xmlParserCtxtPtr ctxt) {    int ret;    if (ctxt->spaceNr <= 0) return(0);    ctxt->spaceNr--;    if (ctxt->spaceNr > 0)	ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];    else        ctxt->space = &ctxt->spaceTab[0];    ret = ctxt->spaceTab[ctxt->spaceNr];    ctxt->spaceTab[ctxt->spaceNr] = -1;    return(ret);}/* * Macros for accessing the content. Those should be used only by the parser, * and not exported. * * Dirty macros, i.e. one often need to make assumption on the context to * use them * *   CUR_PTR return the current pointer to the xmlChar to be parsed. *           To be used with extreme caution since operations consuming *           characters may move the input buffer to a different location ! *   CUR     returns the current xmlChar value, i.e. a 8 bit value if compiled *           This should be used internally by the parser *           only to compare to ASCII values otherwise it would break when *           running with UTF-8 encoding. *   RAW     same as CUR but in the input buffer, bypass any token *           extraction that may have been done *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only *           to compare on ASCII based substring. *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined *           strings without newlines within the parser. *   NEXT1(l) Skip 1 xmlChar, and must also be used only to skip 1 non-newline ASCII  *           defined char within the parser. * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding * *   NEXT    Skip to the next character, this does the proper decoding *           in UTF-8 mode. It also pop-up unfinished entities on the fly. *   NEXTL(l) Skip the current unicode character of l xmlChars long. *   CUR_CHAR(l) returns the current unicode character (int), set l *           to the number of xmlChars used for the encoding [0-5]. *   CUR_SCHAR  same but operate on a string instead of the context *   COPY_BUF  copy the current unicode char to the target buffer, increment *            the index *   GROW, SHRINK  handling of input buffers */#define RAW (*ctxt->input->cur)#define CUR (*ctxt->input->cur)#define NXT(val) ctxt->input->cur[(val)]#define CUR_PTR ctxt->input->cur#define CMP4( s, c1, c2, c3, c4 ) \  ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \    ((unsigned char *) s)[ 2 ] == c3 && ((unsigned char *) s)[ 3 ] == c4 )#define CMP5( s, c1, c2, c3, c4, c5 ) \  ( CMP4( s, c1, c2, c3, c4 ) && ((unsigned char *) s)[ 4 ] == c5 )#define CMP6( s, c1, c2, c3, c4, c5, c6 ) \  ( CMP5( s, c1, c2, c3, c4, c5 ) && ((unsigned char *) s)[ 5 ] == c6 )#define CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) \  ( CMP6( s, c1, c2, c3, c4, c5, c6 ) && ((unsigned char *) s)[ 6 ] == c7 )#define CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) \  ( CMP7( s, c1, c2, c3, c4, c5, c6, c7 ) && ((unsigned char *) s)[ 7 ] == c8 )#define CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) \  ( CMP8( s, c1, c2, c3, c4, c5, c6, c7, c8 ) && \    ((unsigned char *) s)[ 8 ] == c9 )#define CMP10( s, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) \  ( CMP9( s, c1, c2, c3, c4, c5, c6, c7, c8, c9 ) && \    ((unsigned char *) s)[ 9 ] == c10 )#define SKIP(val) do {							\    ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val);			\    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\    if ((*ctxt->input->cur == 0) &&					\        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\	    xmlPopInput(ctxt);						\  } while (0)#define SKIPL(val) do {							\    int skipl;								\    for(skipl=0; skipl<val; skipl++) {					\    	if (*(ctxt->input->cur) == '\n') {				\	ctxt->input->line++; ctxt->input->col = 1;			\    	} else ctxt->input->col++;					\    	ctxt->nbChars++;						\	ctxt->input->cur++;						\    }									\    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\    if ((*ctxt->input->cur == 0) &&					\        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))		\	    xmlPopInput(ctxt);						\  } while (0)#define SHRINK if ((ctxt->progressive == 0) &&				\		   (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \		   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \	xmlSHRINK (ctxt);static void xmlSHRINK (xmlParserCtxtPtr ctxt) {    xmlParserInputShrink(ctxt->input);    if ((*ctxt->input->cur == 0) &&        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))	    xmlPopInput(ctxt);  }#define GROW if ((ctxt->progressive == 0) &&				\		 (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))	\	xmlGROW (ctxt);static void xmlGROW (xmlParserCtxtPtr ctxt) {    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);    if ((*ctxt->input->cur == 0) &&        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))	    xmlPopInput(ctxt);}#define SKIP_BLANKS xmlSkipBlankChars(ctxt)#define NEXT xmlNextChar(ctxt)#define NEXT1 {								\	ctxt->input->col++;						\	ctxt->input->cur++;						\	ctxt->nbChars++;						\	if (*ctxt->input->cur == 0)					\	    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);		\    }#define NEXTL(l) do {							\    if (*(ctxt->input->cur) == '\n') {					\	ctxt->input->line++; ctxt->input->col = 1;			\    } else ctxt->input->col++;						\    ctxt->input->cur += l;				\    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\  } while (0)#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)#define COPY_BUF(l,b,i,v)						\    if (l == 1) b[i++] = (xmlChar) v;					\    else i += xmlCopyCharMultiByte(&b[i],v)/** * xmlSkipBlankChars: * @ctxt:  the XML parser context * * skip all blanks character found at that point in the input streams. * It pops up finished entities in the process if allowable at that point. * * Returns the number of space chars skipped */intxmlSkipBlankChars(xmlParserCtxtPtr ctxt) {    int res = 0;    /*     * It's Okay to use CUR/NEXT here since all the blanks are on     * the ASCII range.     */    if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {	const xmlChar *cur;	/*	 * if we are in the document content, go really fast	 */	cur = ctxt->input->cur;	while (IS_BLANK_CH(*cur)) {	    if (*cur == '\n') {		ctxt->input->line++; ctxt->input->col = 1;	    }	    cur++;	    res++;	    if (*cur == 0) {		ctxt->input->cur = cur;		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);		cur = ctxt->input->cur;	    }	}	ctxt->input->cur = cur;    } else {	int cur;	do {	    cur = CUR;	    while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */		NEXT;		cur = CUR;		res++;	    }	    while ((cur == 0) && (ctxt->inputNr > 1) &&		   (ctxt->instate != XML_PARSER_COMMENT)) {		xmlPopInput(ctxt);		cur = CUR;	    }	    /*	     * Need to handle support of entities branching here	     */	    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	} while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */    }    return(res);}/************************************************************************ *									* *		Commodity functions to handle entities			* *									* ************************************************************************//** * xmlPopInput: * @ctxt:  an XML parser context * * xmlPopInput: the current input pointed by ctxt->input came to an end *          pop it and return the next char. * * Returns the current xmlChar in the parser context */xmlCharxmlPopInput(xmlParserCtxtPtr ctxt) {    if ((ctxt == NULL) || (ctxt->inputNr <= 1)) return(0);    if (xmlParserDebugEntities)	xmlGenericError(xmlGenericErrorContext,		"Popping input %d\n", ctxt->inputNr);    xmlFreeInputStream(inputPop(ctxt));    if ((*ctxt->input->cur == 0) &&        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))	    return(xmlPopInput(ctxt));    return(CUR);}/** * xmlPushInput: * @ctxt:  an XML parser context * @input:  an XML parser input fragment (entity, XML fragment ...). * * xmlPushInput: switch to a new input stream which is stacked on top *               of the previous one(s). */voidxmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {    if (input == NULL) return;    if (xmlParserDebugEntities) {	if ((ctxt->input != NULL) && (ctxt->input->filename))	    xmlGenericError(xmlGenericErrorContext,		    "%s(%d): ", ctxt->input->filename,		    ctxt->input->line);	xmlGenericError(xmlGenericErrorContext,		"Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);    }    inputPush(ctxt, input);    GROW;}/** * xmlParseCharRef: * @ctxt:  an XML parser context * * parse Reference declarations * * [66] CharRef ::= '&#' [0-9]+ ';' | *                  '&#x' [0-9a-fA-F]+ ';' * * [ WFC: Legal Character ] * Characters referred to using character references must match the * production for Char.  * * Returns the value parsed (as an int), 0 in case of error */intxmlParseCharRef(xmlParserCtxtPtr ctxt) {    unsigned int val = 0;    int count = 0;    unsigned int outofrange = 0;    /*     * Using RAW/CUR/NEXT is okay since we are working on ASCII range here     */    if ((RAW == '&') && (NXT(1) == '#') &&        (NXT(2) == 'x')) {	SKIP(3);	GROW;	while (RAW != ';') { /* loop blocked by count */	    if (count++ > 20) {		count = 0;		GROW;	    }	    if ((RAW >= '0') && (RAW <= '9')) 	        val = val * 16 + (CUR - '0');	    else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))	        val = val * 16 + (CUR - 'a') + 10;	    else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))	        val = val * 16 + (CUR - 'A') + 10;	    else {		xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);		val = 0;		break;	    }	    if (val > 0x10FFFF)	        outofrange = val;	    NEXT;	    count++;	}	if (RAW == ';') {	    /* on purpose to avoid reentrancy problems with NEXT and SKIP */	    ctxt->input->col++;	    ctxt->nbChars ++;	    ctxt->input->cur++;	}    } else if  ((RAW == '&') && (NXT(1) == '#')) {	SKIP(2);	GROW;	while (RAW != ';') { /* loop blocked by count */	    if (count++ > 20) {		count = 0;		GROW;	    }	    if ((RAW >= '0') && (RAW <= '9')) 	        val = val * 10 + (CUR - '0');	    else {		xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);		val = 0;		break;	    }	    if (val > 0x10FFFF)	        outofrange = val;	    NEXT;	    count++;	}	if (RAW == ';') {	    /* on purpose to avoid reentrancy problems with NEXT and SKIP */	    ctxt->input->col++;	    ctxt->nbChars ++;	    ctxt->input->cur++;	}    } else {        xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);    }    /*     * [ WFC: Legal Character ]     * Characters referred to using character references must match the     * production for Char.      */    if ((IS_CHAR(val) && (outofrange == 0))) {        return(val);    } else {        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,                          "xmlParseCharRef: invalid xmlChar value %d\n",	                  val);    }    return(0);}/** * xmlParseStringCharRef: * @ctxt:  an XML parser context * @str:  a pointer to an index in the string * * parse Reference declarations, variant parsing from a string rather * than an an input flow. * * [66] CharRef ::= '&#' [0-9]+ ';' | *                  '&#x' [0-9a-fA-F]+ ';' * * [ WFC: Legal Character ] * Characters referred to using character references must match the * production for Char.  *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -