📄 xmlreader.c.svn-base
字号:
static voidxmlTextReaderFreeIDTable(xmlIDTablePtr table) { xmlHashFree(table, (xmlHashDeallocator) xmlFreeID);}/** * xmlTextReaderFreeDoc: * @reader: the xmlTextReaderPtr used * @cur: pointer to the document * * Free up all the structures used by a document, tree included. */static voidxmlTextReaderFreeDoc(xmlTextReaderPtr reader, xmlDocPtr cur) { xmlDtdPtr extSubset, intSubset; if (cur == NULL) return; if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue)) xmlDeregisterNodeDefaultValue((xmlNodePtr) cur); /* * Do this before freeing the children list to avoid ID lookups */ if (cur->ids != NULL) xmlTextReaderFreeIDTable((xmlIDTablePtr) cur->ids); cur->ids = NULL; if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs); cur->refs = NULL; extSubset = cur->extSubset; intSubset = cur->intSubset; if (intSubset == extSubset) extSubset = NULL; if (extSubset != NULL) { xmlUnlinkNode((xmlNodePtr) cur->extSubset); cur->extSubset = NULL; xmlFreeDtd(extSubset); } if (intSubset != NULL) { xmlUnlinkNode((xmlNodePtr) cur->intSubset); cur->intSubset = NULL; xmlFreeDtd(intSubset); } if (cur->children != NULL) xmlTextReaderFreeNodeList(reader, cur->children); if (cur->version != NULL) xmlFree((char *) cur->version); if (cur->name != NULL) xmlFree((char *) cur->name); if (cur->encoding != NULL) xmlFree((char *) cur->encoding); if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs); if (cur->URL != NULL) xmlFree((char *) cur->URL); if (cur->dict != NULL) xmlDictFree(cur->dict); xmlFree(cur);}/************************************************************************ * * * The reader core parser * * * ************************************************************************/#ifdef DEBUG_READERstatic voidxmlTextReaderDebug(xmlTextReaderPtr reader) { if ((reader == NULL) || (reader->ctxt == NULL)) { fprintf(stderr, "xmlTextReader NULL\n"); return; } fprintf(stderr, "xmlTextReader: state %d depth %d ", reader->state, reader->depth); if (reader->node == NULL) { fprintf(stderr, "node = NULL\n"); } else { fprintf(stderr, "node %s\n", reader->node->name); } fprintf(stderr, " input: base %d, cur %d, depth %d: ", reader->base, reader->cur, reader->ctxt->nodeNr); if (reader->input->buffer == NULL) { fprintf(stderr, "buffer is NULL\n"); } else {#ifdef LIBXML_DEBUG_ENABLED xmlDebugDumpString(stderr, &reader->input->buffer->content[reader->cur]);#endif fprintf(stderr, "\n"); }}#endif/** * xmlTextReaderEntPush: * @reader: the xmlTextReaderPtr used * @value: the entity reference node * * Pushes a new entity reference node on top of the entities stack * * Returns 0 in case of error, the index in the stack otherwise */static intxmlTextReaderEntPush(xmlTextReaderPtr reader, xmlNodePtr value){ if (reader->entMax <= 0) { reader->entMax = 10; reader->entTab = (xmlNodePtr *) xmlMalloc(reader->entMax * sizeof(reader->entTab[0])); if (reader->entTab == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n"); return (0); } } if (reader->entNr >= reader->entMax) { reader->entMax *= 2; reader->entTab = (xmlNodePtr *) xmlRealloc(reader->entTab, reader->entMax * sizeof(reader->entTab[0])); if (reader->entTab == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n"); return (0); } } reader->entTab[reader->entNr] = value; reader->ent = value; return (reader->entNr++);}/** * xmlTextReaderEntPop: * @reader: the xmlTextReaderPtr used * * Pops the top element entity from the entities stack * * Returns the entity just removed */static xmlNodePtrxmlTextReaderEntPop(xmlTextReaderPtr reader){ xmlNodePtr ret; if (reader->entNr <= 0) return (0); reader->entNr--; if (reader->entNr > 0) reader->ent = reader->entTab[reader->entNr - 1]; else reader->ent = NULL; ret = reader->entTab[reader->entNr]; reader->entTab[reader->entNr] = 0; return (ret);}/** * xmlTextReaderStartElement: * @ctx: the user data (XML parser context) * @fullname: The element name, including namespace prefix * @atts: An array of name/value attributes pairs, NULL terminated * * called when an opening tag has been processed. */static voidxmlTextReaderStartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) { xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlTextReaderPtr reader = ctxt->_private;#ifdef DEBUG_CALLBACKS printf("xmlTextReaderStartElement(%s)\n", fullname);#endif if ((reader != NULL) && (reader->startElement != NULL)) { reader->startElement(ctx, fullname, atts); if ((ctxt->node != NULL) && (ctxt->input != NULL) && (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') && (ctxt->input->cur[1] == '>')) ctxt->node->extra = NODE_IS_EMPTY; } if (reader != NULL) reader->state = XML_TEXTREADER_ELEMENT;}/** * xmlTextReaderEndElement: * @ctx: the user data (XML parser context) * @fullname: The element name, including namespace prefix * * called when an ending tag has been processed. */static voidxmlTextReaderEndElement(void *ctx, const xmlChar *fullname) { xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlTextReaderPtr reader = ctxt->_private;#ifdef DEBUG_CALLBACKS printf("xmlTextReaderEndElement(%s)\n", fullname);#endif if ((reader != NULL) && (reader->endElement != NULL)) { reader->endElement(ctx, fullname); }}/** * xmlTextReaderStartElementNs: * @ctx: the user data (XML parser context) * @localname: the local name of the element * @prefix: the element namespace prefix if available * @URI: the element namespace name if available * @nb_namespaces: number of namespace definitions on that node * @namespaces: pointer to the array of prefix/URI pairs namespace definitions * @nb_attributes: the number of attributes on that node * nb_defaulted: the number of defaulted attributes. * @attributes: pointer to the array of (localname/prefix/URI/value/end) * attribute values. * * called when an opening tag has been processed. */static voidxmlTextReaderStartElementNs(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlTextReaderPtr reader = ctxt->_private;#ifdef DEBUG_CALLBACKS printf("xmlTextReaderStartElementNs(%s)\n", localname);#endif if ((reader != NULL) && (reader->startElementNs != NULL)) { reader->startElementNs(ctx, localname, prefix, URI, nb_namespaces, namespaces, nb_attributes, nb_defaulted, attributes); if ((ctxt->node != NULL) && (ctxt->input != NULL) && (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') && (ctxt->input->cur[1] == '>')) ctxt->node->extra = NODE_IS_EMPTY; } if (reader != NULL) reader->state = XML_TEXTREADER_ELEMENT;}/** * xmlTextReaderEndElementNs: * @ctx: the user data (XML parser context) * @localname: the local name of the element * @prefix: the element namespace prefix if available * @URI: the element namespace name if available * * called when an ending tag has been processed. */static voidxmlTextReaderEndElementNs(void *ctx, const xmlChar * localname, const xmlChar * prefix, const xmlChar * URI){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlTextReaderPtr reader = ctxt->_private;#ifdef DEBUG_CALLBACKS printf("xmlTextReaderEndElementNs(%s)\n", localname);#endif if ((reader != NULL) && (reader->endElementNs != NULL)) { reader->endElementNs(ctx, localname, prefix, URI); }}/** * xmlTextReaderCharacters: * @ctx: the user data (XML parser context) * @ch: a xmlChar string * @len: the number of xmlChar * * receiving some chars from the parser. */static voidxmlTextReaderCharacters(void *ctx, const xmlChar *ch, int len){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlTextReaderPtr reader = ctxt->_private;#ifdef DEBUG_CALLBACKS printf("xmlTextReaderCharacters()\n");#endif if ((reader != NULL) && (reader->characters != NULL)) { reader->characters(ctx, ch, len); }}/** * xmlTextReaderCDataBlock: * @ctx: the user data (XML parser context) * @value: The pcdata content * @len: the block length * * called when a pcdata block has been parsed */static voidxmlTextReaderCDataBlock(void *ctx, const xmlChar *ch, int len){ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; xmlTextReaderPtr reader = ctxt->_private;#ifdef DEBUG_CALLBACKS printf("xmlTextReaderCDataBlock()\n");#endif if ((reader != NULL) && (reader->cdataBlock != NULL)) { reader->cdataBlock(ctx, ch, len); }}/** * xmlTextReaderPushData: * @reader: the xmlTextReaderPtr used * * Push data down the progressive parser until a significant callback * got raised. * * Returns -1 in case of failure, 0 otherwise */static intxmlTextReaderPushData(xmlTextReaderPtr reader) { xmlBufferPtr inbuf; int val, s; xmlTextReaderState oldstate; if ((reader->input == NULL) || (reader->input->buffer == NULL)) return(-1); oldstate = reader->state; reader->state = XML_TEXTREADER_NONE; inbuf = reader->input->buffer; while (reader->state == XML_TEXTREADER_NONE) { if (inbuf->use < reader->cur + CHUNK_SIZE) { /* * Refill the buffer unless we are at the end of the stream */ if (reader->mode != XML_TEXTREADER_MODE_EOF) { val = xmlParserInputBufferRead(reader->input, 4096); if ((val == 0) && (inbuf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)) { if (inbuf->use == reader->cur) { reader->mode = XML_TEXTREADER_MODE_EOF; reader->state = oldstate; } } else if (val < 0) { reader->mode = XML_TEXTREADER_MODE_EOF; reader->state = oldstate; if ((oldstate != XML_TEXTREADER_START) || (reader->ctxt->myDoc != NULL)) return(val); } else if (val == 0) { /* mark the end of the stream and process the remains */ reader->mode = XML_TEXTREADER_MODE_EOF; break; } } else break; } /* * parse by block of CHUNK_SIZE bytes, various tests show that * it's the best tradeoff at least on a 1.2GH Duron */ if (inbuf->use >= reader->cur + CHUNK_SIZE) { val = xmlParseChunk(reader->ctxt, (const char *) &inbuf->content[reader->cur], CHUNK_SIZE, 0); reader->cur += CHUNK_SIZE; if ((val != 0) && (reader->ctxt->wellFormed == 0)) return(-1); } else { s = inbuf->use - reader->cur; val = xmlParseChunk(reader->ctxt, (const char *) &inbuf->content[reader->cur], s, 0); reader->cur += s; if ((val != 0) && (reader->ctxt->wellFormed == 0)) return(-1); break; } } /* * Discard the consumed input when needed and possible */ if (reader->mode == XML_TEXTREADER_MODE_INTERACTIVE) { if (inbuf->alloc != XML_BUFFER_ALLOC_IMMUTABLE) { if ((reader->cur >= 4096) && (inbuf->use - reader->cur <= CHUNK_SIZE)) { val = xmlBufferShrink(inbuf, reader->cur); if (val >= 0) { reader->cur -= val; } } } } /* * At the end of the stream signal that the work is done to the Push * parser. */ else if (reader->mode == XML_TEXTREADER_MODE_EOF) { if (reader->mode != XML_TEXTREADER_DONE) { s = inbuf->use - reader->cur; val = xmlParseChunk(reader->ctxt, (const char *) &inbuf->content[reader->cur], s, 1); reader->cur = inbuf->use; reader->mode = XML_TEXTREADER_DONE; if ((val != 0) && (reader->ctxt->wellFormed == 0)) return(-1); } } reader->state = oldstate; return(0);}#ifdef LIBXML_REGEXP_ENABLED/** * xmlTextReaderValidatePush: * @reader: the xmlTextReaderPtr used * * Push the current node for validation */static voidxmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED) { xmlNodePtr node = reader->node;#ifdef LIBXML_VALID_ENABLED if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) && (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) { if ((node->ns == NULL) || (node->ns->prefix == NULL)) { reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt, reader->ctxt->myDoc, node, node->name); } else { /* TODO use the BuildQName interface */ xmlChar *qname; qname = xmlStrdup(node->ns->prefix); qname = xmlStrcat(qname, BAD_CAST ":"); qname = xmlStrcat(qname, node->name); reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt, reader->ctxt->myDoc, node, qname); if (qname != NULL) xmlFree(qname); } }#endif /* LIBXML_VALID_ENABLED */#ifdef LIBXML_SCHEMAS_ENABLED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -