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

📄 parser.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 5 页
字号:
 * Returns the value parsed (as an int), 0 in case of error, str will be *         updated to the current value of the index */static intxmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {    const xmlChar *ptr;    xmlChar cur;    unsigned int val = 0;    unsigned int outofrange = 0;    if ((str == NULL) || (*str == NULL)) return(0);    ptr = *str;    cur = *ptr;    if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {	ptr += 3;	cur = *ptr;	while (cur != ';') { /* Non input consuming loop */	    if ((cur >= '0') && (cur <= '9')) 	        val = val * 16 + (cur - '0');	    else if ((cur >= 'a') && (cur <= 'f'))	        val = val * 16 + (cur - 'a') + 10;	    else if ((cur >= 'A') && (cur <= 'F'))	        val = val * 16 + (cur - 'A') + 10;	    else {		xmlFatalErr(ctxt, XML_ERR_INVALID_HEX_CHARREF, NULL);		val = 0;		break;	    }	    if (val > 0x10FFFF)	        outofrange = val;	    ptr++;	    cur = *ptr;	}	if (cur == ';')	    ptr++;    } else if  ((cur == '&') && (ptr[1] == '#')){	ptr += 2;	cur = *ptr;	while (cur != ';') { /* Non input consuming loops */	    if ((cur >= '0') && (cur <= '9')) 	        val = val * 10 + (cur - '0');	    else {		xmlFatalErr(ctxt, XML_ERR_INVALID_DEC_CHARREF, NULL);		val = 0;		break;	    }	    if (val > 0x10FFFF)	        outofrange = val;	    ptr++;	    cur = *ptr;	}	if (cur == ';')	    ptr++;    } else {	xmlFatalErr(ctxt, XML_ERR_INVALID_CHARREF, NULL);	return(0);    }    *str = ptr;    /*     * [ 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,			  "xmlParseStringCharRef: invalid xmlChar value %d\n",			  val);    }    return(0);}/** * xmlNewBlanksWrapperInputStream: * @ctxt:  an XML parser context * @entity:  an Entity pointer * * Create a new input stream for wrapping * blanks around a PEReference * * Returns the new input stream or NULL */ static void deallocblankswrapper (xmlChar *str) {xmlFree(str);} static xmlParserInputPtrxmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {    xmlParserInputPtr input;    xmlChar *buffer;    size_t length;    if (entity == NULL) {	xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,	            "xmlNewBlanksWrapperInputStream entity\n");	return(NULL);    }    if (xmlParserDebugEntities)	xmlGenericError(xmlGenericErrorContext,		"new blanks wrapper for entity: %s\n", entity->name);    input = xmlNewInputStream(ctxt);    if (input == NULL) {	return(NULL);    }    length = xmlStrlen(entity->name) + 5;    buffer = xmlMallocAtomic(length);    if (buffer == NULL) {	xmlErrMemory(ctxt, NULL);    	return(NULL);    }    buffer [0] = ' ';    buffer [1] = '%';    buffer [length-3] = ';';    buffer [length-2] = ' ';    buffer [length-1] = 0;    memcpy(buffer + 2, entity->name, length - 5);    input->free = deallocblankswrapper;    input->base = buffer;    input->cur = buffer;    input->length = length;    input->end = &buffer[length];    return(input);}/** * xmlParserHandlePEReference: * @ctxt:  the parser context *  * [69] PEReference ::= '%' Name ';' * * [ WFC: No Recursion ] * A parsed entity must not contain a recursive * reference to itself, either directly or indirectly.  * * [ WFC: Entity Declared ] * In a document without any DTD, a document with only an internal DTD * subset which contains no parameter entity references, or a document * with "standalone='yes'", ...  ... The declaration of a parameter * entity must precede any reference to it... * * [ VC: Entity Declared ] * In a document with an external subset or external parameter entities * with "standalone='no'", ...  ... The declaration of a parameter entity * must precede any reference to it... * * [ WFC: In DTD ] * Parameter-entity references may only appear in the DTD. * NOTE: misleading but this is handled. * * A PEReference may have been detected in the current input stream * the handling is done accordingly to  *      http://www.w3.org/TR/REC-xml#entproc * i.e.  *   - Included in literal in entity values *   - Included as Parameter Entity reference within DTDs */voidxmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {    const xmlChar *name;    xmlEntityPtr entity = NULL;    xmlParserInputPtr input;    if (RAW != '%') return;    switch(ctxt->instate) {	case XML_PARSER_CDATA_SECTION:	    return;        case XML_PARSER_COMMENT:	    return;	case XML_PARSER_START_TAG:	    return;	case XML_PARSER_END_TAG:	    return;        case XML_PARSER_EOF:	    xmlFatalErr(ctxt, XML_ERR_PEREF_AT_EOF, NULL);	    return;        case XML_PARSER_PROLOG:	case XML_PARSER_START:	case XML_PARSER_MISC:	    xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);	    return;	case XML_PARSER_ENTITY_DECL:        case XML_PARSER_CONTENT:        case XML_PARSER_ATTRIBUTE_VALUE:        case XML_PARSER_PI:	case XML_PARSER_SYSTEM_LITERAL:	case XML_PARSER_PUBLIC_LITERAL:	    /* we just ignore it there */	    return;        case XML_PARSER_EPILOG:	    xmlFatalErr(ctxt, XML_ERR_PEREF_IN_EPILOG, NULL);	    return;	case XML_PARSER_ENTITY_VALUE:	    /*	     * NOTE: in the case of entity values, we don't do the	     *       substitution here since we need the literal	     *       entity value to be able to save the internal	     *       subset of the document.	     *       This will be handled by xmlStringDecodeEntities	     */	    return;        case XML_PARSER_DTD:	    /*	     * [WFC: Well-Formedness Constraint: PEs in Internal Subset]	     * In the internal DTD subset, parameter-entity references	     * can occur only where markup declarations can occur, not	     * within markup declarations.	     * In that case this is handled in xmlParseMarkupDecl	     */	    if ((ctxt->external == 0) && (ctxt->inputNr == 1))		return;	    if (IS_BLANK_CH(NXT(1)) || NXT(1) == 0)		return;            break;        case XML_PARSER_IGNORE:            return;    }    NEXT;    name = xmlParseName(ctxt);    if (xmlParserDebugEntities)	xmlGenericError(xmlGenericErrorContext,		"PEReference: %s\n", name);    if (name == NULL) {	xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL);    } else {	if (RAW == ';') {	    NEXT;	    if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))		entity = ctxt->sax->getParameterEntity(ctxt->userData, name);	    if (entity == NULL) {	        		/*		 * [ WFC: Entity Declared ]		 * In a document without any DTD, a document with only an		 * internal DTD subset which contains no parameter entity		 * references, or a document with "standalone='yes'", ...		 * ... The declaration of a parameter entity must precede		 * any reference to it...		 */		if ((ctxt->standalone == 1) ||		    ((ctxt->hasExternalSubset == 0) &&		     (ctxt->hasPErefs == 0))) {		    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,			 "PEReference: %%%s; not found\n", name);	        } else {		    /*		     * [ VC: Entity Declared ]		     * In a document with an external subset or external		     * parameter entities with "standalone='no'", ...		     * ... The declaration of a parameter entity must precede		     * any reference to it...		     */		    if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) {		        xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY,			                 "PEReference: %%%s; not found\n",				         name);		    } else 		        xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY,			              "PEReference: %%%s; not found\n",				      name, NULL);		    ctxt->valid = 0;		}	    } else if (ctxt->input->free != deallocblankswrapper) {		    input = xmlNewBlanksWrapperInputStream(ctxt, entity);		    xmlPushInput(ctxt, input);	    } else {	        if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||		    (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {		    xmlChar start[4];		    xmlCharEncoding enc;		    /*		     * handle the extra spaces added before and after		     * c.f. http://www.w3.org/TR/REC-xml#as-PE		     * this is done independently.		     */		    input = xmlNewEntityInputStream(ctxt, entity);		    xmlPushInput(ctxt, input);		    /* 		     * Get the 4 first bytes and decode the charset		     * if enc != XML_CHAR_ENCODING_NONE		     * plug some encoding conversion routines.		     * Note that, since we may have some non-UTF8		     * encoding (like UTF16, bug 135229), the 'length'		     * is not known, but we can calculate based upon		     * the amount of data in the buffer.		     */		    GROW		    if ((ctxt->input->end - ctxt->input->cur)>=4) {			start[0] = RAW;			start[1] = NXT(1);			start[2] = NXT(2);			start[3] = NXT(3);			enc = xmlDetectCharEncoding(start, 4);			if (enc != XML_CHAR_ENCODING_NONE) {			    xmlSwitchEncoding(ctxt, enc);			}		    }		    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&			(CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) &&			(IS_BLANK_CH(NXT(5)))) {			xmlParseTextDecl(ctxt);		    }		} else {		    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER,			     "PEReference: %s is not a parameter entity\n",				      name);		}	    }	} else {	    xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL);	}    }}/* * Macro used to grow the current buffer. */#define growBuffer(buffer) {						\    xmlChar *tmp;							\    buffer##_size *= 2;							\    tmp = (xmlChar *)							\    		xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));	\    if (tmp == NULL) goto mem_error;					\    buffer = tmp;							\}/** * xmlStringLenDecodeEntities: * @ctxt:  the parser context * @str:  the input string * @len: the string length * @what:  combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF * @end:  an end marker xmlChar, 0 if none * @end2:  an end marker xmlChar, 0 if none * @end3:  an end marker xmlChar, 0 if none *  * Takes a entity string content and process to do the adequate substitutions. * * [67] Reference ::= EntityRef | CharRef * * [69] PEReference ::= '%' Name ';' * * Returns A newly allocated string with the substitution done. The caller *      must deallocate it ! */xmlChar *xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,		      int what, xmlChar end, xmlChar  end2, xmlChar end3) {    xmlChar *buffer = NULL;    int buffer_size = 0;    xmlChar *current = NULL;    const xmlChar *last;    xmlEntityPtr ent;    int c,l;    int nbchars = 0;    if ((ctxt == NULL) || (str == NULL) || (len < 0))	return(NULL);    last = str + len;    if (ctxt->depth > 40) {	xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);	return(NULL);    }    /*     * allocate a translation buffer.     */    buffer_size = XML_PARSER_BIG_BUFFER_SIZE;    buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));    if (buffer == NULL) goto mem_error;    /*     * OK loop until we reach one of the ending char or a size limit.     * we are operating on already parsed values.     */    if (str < last)	c = CUR_SCHAR(str, l);    else        c = 0;    while ((c != 0) && (c != end) && /* non input consuming loop */	   (c != end2) && (c != end3)) {	if (c == 0) break;        if ((c == '&') && (str[1] == '#')) {	    int val = xmlParseStringCharRef(ctxt, &str);	    if (val != 0) {		COPY_BUF(0,buffer,nbchars,val);	    }	    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {	        growBuffer(buffer);	    }	} else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {	    if (xmlParserDebugEntities)		xmlGenericError(xmlGenericErrorContext,			"String decoding Entity Reference: %.30s\n",			str);	    ent = xmlParseStringEntityRef(ctxt, &str);	    if ((ent != NULL) &&		(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {		if (ent->content != NULL) {		    COPY_BUF(0,buffer,nbchars,ent->content[0]);		    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {			growBuffer(buffer);		    }		} else {		    xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,			    "predefined entity has no content\n");		}	    } else if ((ent != NULL) && (ent->content != NULL)) {		xmlChar *rep;		ctxt->depth++;		rep = xmlStringDecodeEntities(ctxt, ent->content, what,			                      0, 0, 0);		ctxt->depth--;		if (rep != NULL) {		    current = rep;		    while (*current != 0) { /* non input consuming loop */			buffer[nbchars++] = *current++;			if (nbchars >		            buffer_size - XML_PARSER_BUFFER_SIZE) {			    growBuffer(buffer);			}		    }		    xmlFree(rep);		}	    } else if (ent != NULL) {		int i = xmlStrlen(ent->name);		const xmlChar *cur = ent->name;		buffer[nbchars++] = '&';		if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {		    growBuffer(buffer);		}		for (;i > 0;i--)		    buffer[nbchars++] = *cur++;		buffer[nbchars++] = ';';	    }	} else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {	    if (xmlParserDebugEntities)		xmlGenericError(xmlGenericErrorContext,			"String decoding PE Reference: %.30s\n", str);	    ent = xmlParseStringPEReference(ctxt, &str);	    if (ent != NULL) {		xmlChar *rep;		ctxt

⌨️ 快捷键说明

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