int StartElement(struct XMLReader_t *r, const XMLCH *uri, const XMLCH *localName, const XMLCH *qName, LPXMLVECTOR atts) { union XMLReaderNode_t *rn = XMLVector_Append(r->eventbuffer, NULL); ASSERT_MEM_ABORT(rn); rn->type = XMLREADERTYPE_STARTELEMENT; ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[1], (XMLCH*)uri, rn->startelement.ibuf[0])); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[1], (XMLCH*)localName, rn->startelement.ibuf[1])); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[1], (XMLCH*)qName, rn->startelement.ibuf[2])); if (r->atts->length) ASSERT_MEM_ABORT(_XMLVector_RemoveAll(r->atts)); if (atts->length) { struct XMLReaderAttribute_t *a; int i; for (i=0; i<atts->length; i++) { LPXMLRUNTIMEATT aa = XMLVector_Get(atts, i); ASSERT_MEM_ABORT(a = XMLVector_Append(r->atts, NULL)); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[2], aa->uri, a->ibuf[0])); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[2], aa->localName, a->ibuf[1])); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[2], aa->qname, a->ibuf[2])); ASSERT_MEM_ABORT(IBUF_PUT(&r->buf[2], aa->value, a->ibuf[3])); } } return XML_OK; }
int StartElement(void *UserData, const XMLCH *uri, const XMLCH *localName, const XMLCH *qName, LPXMLVECTOR atts) { LPXMLDTDVALIDATOR v = (LPXMLDTDVALIDATOR)UserData; if (!strcmp(uri, NSVALIDP->wantedUri)) { LPXMLVECTOR attsF; if (v->UserFlag) v->UserFlag = 0; NSVALIDP->elemCount++; if (!atts->length) attsF = atts; else { int i; LPXMLRUNTIMEATT a; if (NSVALIDP->filteredAtts->length) _XMLVector_RemoveAll(NSVALIDP->filteredAtts); for (i=0; i<atts->length; i++) { a = XMLVector_Get(atts, i); if (!*a->uri || !strcmp(a->uri, NSVALIDP->wantedUri)) a = XMLVector_Append(NSVALIDP->filteredAtts, a); ASSERT_MEM_ABORT(a); } attsF = NSVALIDP->filteredAtts; } return DTDValidate_StartElement(v, uri, localName, localName, attsF); } v->UserFlag++; return XML_OK; }
union XMLReaderNode_t *XMLReader_Read(struct XMLReader_t *r) { do { if (r->eventbuffer->length) { if (r->eventbufferpos == r->eventbuffer->length) { /* for (i=0; i<sizeof(r->buf)/sizeof(r->buf[0]); i++) */ if (r->buf[0].len) XMLStringbuf_SetLength(&r->buf[0], 0); if (r->buf[1].len) XMLStringbuf_SetLength(&r->buf[1], 0); if (r->buf[2].len) XMLStringbuf_SetLength(&r->buf[2], 0); _XMLVector_RemoveAll(r->eventbuffer); r->eventbufferpos = 0; } else { union XMLReaderNode_t *rn = XMLVector_Get(r->eventbuffer, r->eventbufferpos); if (r->buf[0].len) { ASSERT_MEM_SETERR(XMLStringbuf_ToString(&r->buf[0])); if (rn->type == XMLREADERTYPE_CHARS) { rn->chars.text = r->buf[0].str; rn->chars.length = r->buf[0].len; } else if (rn->type == XMLREADERTYPE_COMMENT) { rn->comment.text = r->buf[0].str; rn->comment.length = r->buf[0].len; } r->buf[0].len = 0; } else { switch(rn->type) { case XMLREADERTYPE_STARTELEMENT: rn->startelement.uri = IBUF_GET(&r->buf[1], rn->startelement.ibuf[0]); rn->startelement.localname = IBUF_GET(&r->buf[1], rn->startelement.ibuf[1]); rn->startelement.qname = IBUF_GET(&r->buf[1], rn->startelement.ibuf[2]); rn->startelement.atts = r->atts; break; case XMLREADERTYPE_ENDELEMENT: rn->endelement.uri = IBUF_GET(&r->buf[1], rn->endelement.ibuf[0]); rn->endelement.localname = IBUF_GET(&r->buf[1], rn->endelement.ibuf[1]); rn->endelement.qname = IBUF_GET(&r->buf[1], rn->endelement.ibuf[2]); break; } } r->eventbufferpos++; return rn; } } } while (XMLParser_HasMoreEvents(r->parser)); return NULL; }
static void FreeDTDValidator(LPXMLDTDVALIDATOR p, int ForReuse) { if (p->ElementDecls) { struct ElementDecl *pEl, *pEnd; struct FSAState **pS, **pSEnd; pEnd = (struct ElementDecl *)_XMLVector_GetIterP(p->ElementDecls, pEl); for (; pEl!=pEnd; pEl++) { if (pEl->fsa) { pSEnd = (struct FSAState **)_XMLVector_GetIterP(pEl->fsa, pS); for (; pS!=pSEnd; pS++) { if ((*pS)->trans) XMLVector_Free((*pS)->trans); } XMLVector_Free(pEl->fsa); } } if (ForReuse) _XMLVector_RemoveAll(p->ElementDecls); else XMLVector_Free(p->ElementDecls); } /* these are allocated by the parser when XMLFLAG_REPORT_DTD_EXT is set, we're responsible for freeing them: */ if (p->cpNodesPool) XMLPool_FreePool(p->cpNodesPool); if (p->ElementTable) XMLHTable_Destroy(p->ElementTable, NULL, 0); if (p->idTable) XMLHTable_Destroy(p->idTable, NULL, 0); if (ForReuse) { if (p->StatePool && p->StatePool->blocksAllocated) { XMLPool_FreePool(p->StatePool); p->StatePool = XMLPool_Create(sizeof(struct FSAState), 16); if (!p->StatePool) Er_(p, NULL, ERR_XMLDTDV_MEMORY_ALLOC); } return; } if (p->StatePool) XMLPool_FreePool(p->StatePool); if (p->ContextStack) XMLVector_Free(p->ContextStack); free(p); }
int XMLAPI XMLParser_ParseValidateDTD(LPXMLDTDVALIDATOR dtd, LPXMLPARSER parser, LPFNINPUTSRC inputSrc, void *inputData, const XMLCH *encoding) { int ret; if (!dtd || !parser) return 0; if (!inputSrc) ret = (parser->ErrorCode==0); else { dtd->parser = parser; dtd->ErrorCode = dtd->ErrorColumn = dtd->ErrorLine = 0; /* must be set before FreeDTDValidator */ if (*dtd->ErrorString) dtd->ErrorString[0] = '\0'; if (dtd->ContextStack->length) _XMLVector_RemoveAll(dtd->ContextStack); if (dtd->cpNodesPool) { FreeDTDValidator(dtd, 1); if (dtd->ErrorCode) return 0; } dtd->ElementTable = NULL; dtd->cpNodesPool = NULL; dtd->idTable = NULL; /* save handlers: */ dtd->startElementHandler = parser->startElementHandler; dtd->endElementHandler = parser->endElementHandler; dtd->charactersHandler = parser->charactersHandler; dtd->ignorableWhitespaceHandler = parser->ignorableWhitespaceHandler; dtd->elementDeclHandler = parser->elementDeclHandler; dtd->endDTDHandler = parser->endDTDHandler; /* set the validating ones: */ parser->startElementHandler = dtd->startElementHandlerFilter; parser->endElementHandler = dtd->endElementHandlerFilter; parser->charactersHandler = dtd->charactersHandlerFilter; parser->ignorableWhitespaceHandler = dtd->ignorableWhitespaceHandlerFilter; parser->elementDeclHandler = DTDValidate_ElementDecl; parser->endDTDHandler = DTDValidate_EndDTD; _XMLParser_SetFlag(parser, XMLFLAG_REPORT_DTD_EXT, 1); parser->UserData = dtd; ret = XMLParser_Parse(parser, inputSrc, inputData, encoding); if (ret && _XMLParser_GetFlag(parser, XMLFLAG_USE_SIMPLEPULL)) return 1; } if (!ret) { /* Assign ElementTable and content particle pool 'cos validator will be responsible for freeing them and endDTD might not be called */ if (dtd->ElementTable!=parser->prt->cpNames) dtd->ElementTable = parser->prt->cpNames; if (dtd->cpNodesPool!=parser->prt->cpNodesPool) dtd->cpNodesPool = parser->prt->cpNodesPool; } else if (dtd->idTable) { dtd->idTable->userdata = dtd; XMLHTable_Destroy(dtd->idTable, CheckIDREFS, 0); dtd->idTable = NULL; ret = (parser->ErrorCode==0); } if (parser->prt->doctypeStr) { free(parser->prt->doctypeStr); parser->prt->doctypeStr = NULL; } _XMLParser_SetFlag(parser, XMLFLAG_REPORT_DTD_EXT, 0); /* restore handlers: */ parser->startElementHandler = dtd->startElementHandler; parser->endElementHandler = dtd->endElementHandler; parser->charactersHandler = dtd->charactersHandler; parser->ignorableWhitespaceHandler = dtd->ignorableWhitespaceHandler; parser->elementDeclHandler = dtd->elementDeclHandler; parser->endDTDHandler = dtd->endDTDHandler; return ret; }