]> git.ipfire.org Git - thirdparty/squid.git/blame - src/esi/Libxml2Parser.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / esi / Libxml2Parser.cc
CommitLineData
964b44c3 1/*
2cd0bda2 2 * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
964b44c3 3 *
bbc27441
AJ
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.
964b44c3 7 */
8
9/*
10 * The ESI Libxml2 parser is Copyright (c) 2004 by Joachim Bauch
11 * http://www.joachim-bauch.de
12 * mail@joachim-bauch.de
13 */
14
582c2af2 15#include "squid.h"
964b44c3 16
95cd9022 17#if USE_SQUID_ESI && HAVE_LIBXML2
964b44c3 18
f99c2cfe 19#include "esi/Libxml2Parser.h"
964b44c3 20
21// the global document that will store the resolved entity
22// definitions
23static htmlDocPtr entity_doc = NULL;
24
019db3c6 25EsiParserDefinition(ESILibxml2Parser);
c2d4889f 26
964b44c3 27// the SAX callback functions
28void esi_startElementSAXFunc(void * ctx, const xmlChar * name, const xmlChar ** atts)
29{
30 int count=0;
31 xmlChar **tmp = (xmlChar **)atts;
32
33 while (tmp && *tmp != NULL) {
cb4185f1
FC
34 ++count;
35 ++tmp;
964b44c3 36 }
37
38 // we increased on every key and value
39 count /= 2;
40
41 ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
42
43 p->getClient()->start((const char *)name, (const char **)atts, count);
44}
45
46void esi_endElementSAXFunc(void * ctx, const xmlChar * name)
47{
48 ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
49 p->getClient()->end((const char *)name);
50}
51
52void esi_commentSAXFunc(void * ctx, const xmlChar * value)
53{
54 ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
55 p->getClient()->parserComment((const char *)value);
56}
57
58void esi_charactersSAXFunc(void *ctx, const xmlChar *ch, int len)
59{
60 ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
61 p->getClient()->parserDefault((const char *)ch, len);
62}
63
64xmlEntityPtr esi_getEntitySAXFunc(void * ctx, const xmlChar * name)
65{
66 xmlEntityPtr res = xmlGetDocEntity(entity_doc, name);
67
68 if (res == NULL) {
69 const htmlEntityDesc *ent = htmlEntityLookup(name);
70
71 if (ent != NULL) {
72 char tmp[32];
da783331 73 snprintf(tmp, 32, "&#%d;", ent->value);
964b44c3 74 res = xmlAddDocEntity(entity_doc, (const xmlChar *)name, XML_INTERNAL_GENERAL_ENTITY, NULL, NULL, (const xmlChar *)tmp);
75 }
76 }
77
78 return res;
79}
80
81ESILibxml2Parser::ESILibxml2Parser(ESIParserClient *aClient) : theClient (aClient)
82{
83 xmlSAXHandler sax;
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;
91
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);
95
96 if (entity_doc == NULL)
97 entity_doc = htmlNewDoc(NULL, NULL);
98}
99
100ESILibxml2Parser::~ESILibxml2Parser()
101{
102 xmlFreeParserCtxt(parser);
103 parser = NULL;
104}
105
106bool
107ESILibxml2Parser::parse(char const *dataToParse, size_t const lengthOfData, bool const endOfStream)
108{
109 return (xmlParseChunk(parser, dataToParse, lengthOfData, endOfStream) == 0);
110}
111
137a13ea 112long int
964b44c3 113ESILibxml2Parser::lineNumber() const
114{
137a13ea 115 return (long int)xmlSAX2GetLineNumber(parser);
964b44c3 116}
117
118char const *
119ESILibxml2Parser::errorString() const
120{
121 xmlErrorPtr error = xmlGetLastError();
122
123 if (error == NULL)
124 return NULL;
125
126 return error->message;
127}
da783331
AJ
128
129#endif /* USE_SQUID_ESI */
f53969cc 130