2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 * The ESI Libxml2 parser is Copyright (c) 2004 by Joachim Bauch
11 * http://www.joachim-bauch.de
12 * mail@joachim-bauch.de
17 #if USE_SQUID_ESI && HAVE_LIBXML2
19 #include "esi/Libxml2Parser.h"
21 // the global document that will store the resolved entity
23 static htmlDocPtr entity_doc
= NULL
;
25 EsiParserDefinition(ESILibxml2Parser
);
27 // the SAX callback functions
28 void esi_startElementSAXFunc(void * ctx
, const xmlChar
* name
, const xmlChar
** atts
)
31 xmlChar
**tmp
= (xmlChar
**)atts
;
33 while (tmp
&& *tmp
!= NULL
) {
38 // we increased on every key and value
41 ESILibxml2Parser
*p
= (ESILibxml2Parser
*)ctx
;
43 p
->getClient()->start((const char *)name
, (const char **)atts
, count
);
46 void esi_endElementSAXFunc(void * ctx
, const xmlChar
* name
)
48 ESILibxml2Parser
*p
= (ESILibxml2Parser
*)ctx
;
49 p
->getClient()->end((const char *)name
);
52 void esi_commentSAXFunc(void * ctx
, const xmlChar
* value
)
54 ESILibxml2Parser
*p
= (ESILibxml2Parser
*)ctx
;
55 p
->getClient()->parserComment((const char *)value
);
58 void esi_charactersSAXFunc(void *ctx
, const xmlChar
*ch
, int len
)
60 ESILibxml2Parser
*p
= (ESILibxml2Parser
*)ctx
;
61 p
->getClient()->parserDefault((const char *)ch
, len
);
64 xmlEntityPtr
esi_getEntitySAXFunc(void * ctx
, const xmlChar
* name
)
66 xmlEntityPtr res
= xmlGetDocEntity(entity_doc
, name
);
69 const htmlEntityDesc
*ent
= htmlEntityLookup(name
);
73 snprintf(tmp
, 32, "&#%d;", ent
->value
);
74 res
= xmlAddDocEntity(entity_doc
, (const xmlChar
*)name
, XML_INTERNAL_GENERAL_ENTITY
, NULL
, NULL
, (const xmlChar
*)tmp
);
81 ESILibxml2Parser::ESILibxml2Parser(ESIParserClient
*aClient
) : theClient (aClient
)
84 htmlDefaultSAXHandlerInit();
85 memset(&sax
, 0, sizeof(sax
));
86 sax
.startElement
= esi_startElementSAXFunc
;
87 sax
.endElement
= esi_endElementSAXFunc
;
88 sax
.comment
= esi_commentSAXFunc
;
89 sax
.characters
= esi_charactersSAXFunc
;
90 sax
.getEntity
= esi_getEntitySAXFunc
;
92 /* TODO: grab the document encoding from the headers */
93 parser
= xmlCreatePushParserCtxt(&sax
, static_cast<void *>(this), NULL
, 0, NULL
);
94 xmlSetFeature(parser
, "substitute entities", 0);
96 if (entity_doc
== NULL
)
97 entity_doc
= htmlNewDoc(NULL
, NULL
);
100 ESILibxml2Parser::~ESILibxml2Parser()
102 xmlFreeParserCtxt(parser
);
107 ESILibxml2Parser::parse(char const *dataToParse
, size_t const lengthOfData
, bool const endOfStream
)
109 return (xmlParseChunk(parser
, dataToParse
, lengthOfData
, endOfStream
) == 0);
113 ESILibxml2Parser::lineNumber() const
115 return (long int)xmlSAX2GetLineNumber(parser
);
119 ESILibxml2Parser::errorString() const
121 xmlErrorPtr error
= xmlGetLastError();
126 return error
->message
;
129 #endif /* USE_SQUID_ESI */