Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /*  | 
2  |  |  * xmlreader.c: implements the xmlTextReader streaming node API  | 
3  |  |  *  | 
4  |  |  * NOTE:  | 
5  |  |  *   XmlTextReader.Normalization Property won't be supported, since  | 
6  |  |  *     it makes the parser non compliant to the XML recommendation  | 
7  |  |  *  | 
8  |  |  * See Copyright for the status of this software.  | 
9  |  |  *  | 
10  |  |  * daniel@veillard.com  | 
11  |  |  */  | 
12  |  |  | 
13  |  | /*  | 
14  |  |  * TODOs:  | 
15  |  |  *   - XML Schemas validation  | 
16  |  |  */  | 
17  |  | #define IN_LIBXML  | 
18  |  | #include "libxml.h"  | 
19  |  |  | 
20  |  | #ifdef LIBXML_READER_ENABLED  | 
21  |  | #include <string.h> /* for memset() only ! */  | 
22  |  | #include <stdarg.h>  | 
23  |  | #include <ctype.h>  | 
24  |  | #include <stdlib.h>  | 
25  |  |  | 
26  |  | #include <libxml/xmlmemory.h>  | 
27  |  | #include <libxml/xmlIO.h>  | 
28  |  | #include <libxml/xmlreader.h>  | 
29  |  | #include <libxml/parserInternals.h>  | 
30  |  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
31  |  | #include <libxml/relaxng.h>  | 
32  |  | #include <libxml/xmlschemas.h>  | 
33  |  | #endif  | 
34  |  | #include <libxml/uri.h>  | 
35  |  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
36  |  | #include <libxml/xinclude.h>  | 
37  |  | #endif  | 
38  |  | #ifdef LIBXML_PATTERN_ENABLED  | 
39  |  | #include <libxml/pattern.h>  | 
40  |  | #endif  | 
41  |  |  | 
42  |  | #include "private/buf.h"  | 
43  |  | #include "private/tree.h"  | 
44  |  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
45  |  | #include "private/xinclude.h"  | 
46  |  | #endif  | 
47  |  |  | 
48  | 0  | #define MAX_ERR_MSG_SIZE 64000  | 
49  |  |  | 
50  |  | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION  | 
51  |  | /* Keeping free objects can hide memory errors. */  | 
52  | 46.3M  | #define MAX_FREE_NODES 1  | 
53  |  | #else  | 
54  |  | #define MAX_FREE_NODES 100  | 
55  |  | #endif  | 
56  |  |  | 
57  |  | /*  | 
58  |  |  * The following VA_COPY was coded following an example in  | 
59  |  |  * the Samba project.  It may not be sufficient for some  | 
60  |  |  * esoteric implementations of va_list but (hopefully) will  | 
61  |  |  * be sufficient for libxml2.  | 
62  |  |  */  | 
63  |  | #ifndef VA_COPY  | 
64  |  |   #ifdef HAVE_VA_COPY  | 
65  | 0  |     #define VA_COPY(dest, src) va_copy(dest, src)  | 
66  |  |   #else  | 
67  |  |     #ifdef HAVE___VA_COPY  | 
68  |  |       #define VA_COPY(dest,src) __va_copy(dest, src)  | 
69  |  |     #else  | 
70  |  |       #ifndef VA_LIST_IS_ARRAY  | 
71  |  |         #define VA_COPY(dest,src) (dest) = (src)  | 
72  |  |       #else  | 
73  |  |         #include <string.h>  | 
74  |  |         #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))  | 
75  |  |       #endif  | 
76  |  |     #endif  | 
77  |  |   #endif  | 
78  |  | #endif  | 
79  |  |  | 
80  |  | /* #define DEBUG_CALLBACKS */  | 
81  |  | /* #define DEBUG_READER */  | 
82  |  |  | 
83  |  | /**  | 
84  |  |  * TODO:  | 
85  |  |  *  | 
86  |  |  * macro to flag unimplemented blocks  | 
87  |  |  */  | 
88  |  | #define TODO                \  | 
89  | 0  |     xmlGenericError(xmlGenericErrorContext,       \  | 
90  | 0  |       "Unimplemented block at %s:%d\n",       \  | 
91  | 0  |             __FILE__, __LINE__);  | 
92  |  |  | 
93  |  | #ifdef DEBUG_READER  | 
94  |  | #define DUMP_READER xmlTextReaderDebug(reader);  | 
95  |  | #else  | 
96  |  | #define DUMP_READER  | 
97  |  | #endif  | 
98  |  |  | 
99  | 8.19M  | #define CHUNK_SIZE 512  | 
100  |  | /************************************************************************  | 
101  |  |  *                  *  | 
102  |  |  *  The parser: maps the Text Reader API on top of the existing *  | 
103  |  |  *    parsing routines building a tree      *  | 
104  |  |  *                  *  | 
105  |  |  ************************************************************************/  | 
106  |  |  | 
107  | 1.09M  | #define XML_TEXTREADER_INPUT  1  | 
108  | 730k  | #define XML_TEXTREADER_CTXT 2  | 
109  |  |  | 
110  |  | typedef enum { | 
111  |  |     XML_TEXTREADER_NONE = -1,  | 
112  |  |     XML_TEXTREADER_START= 0,  | 
113  |  |     XML_TEXTREADER_ELEMENT= 1,  | 
114  |  |     XML_TEXTREADER_END= 2,  | 
115  |  |     XML_TEXTREADER_EMPTY= 3,  | 
116  |  |     XML_TEXTREADER_BACKTRACK= 4,  | 
117  |  |     XML_TEXTREADER_DONE= 5,  | 
118  |  |     XML_TEXTREADER_ERROR= 6  | 
119  |  | } xmlTextReaderState;  | 
120  |  |  | 
121  |  | typedef enum { | 
122  |  |     XML_TEXTREADER_NOT_VALIDATE = 0,  | 
123  |  |     XML_TEXTREADER_VALIDATE_DTD = 1,  | 
124  |  |     XML_TEXTREADER_VALIDATE_RNG = 2,  | 
125  |  |     XML_TEXTREADER_VALIDATE_XSD = 4  | 
126  |  | } xmlTextReaderValidate;  | 
127  |  |  | 
128  |  | struct _xmlTextReader { | 
129  |  |     int       mode; /* the parsing mode */  | 
130  |  |     xmlDocPtr     doc;    /* when walking an existing doc */  | 
131  |  |     xmlTextReaderValidate       validate;/* is there any validation */  | 
132  |  |     int       allocs; /* what structure were deallocated */  | 
133  |  |     xmlTextReaderState    state;  | 
134  |  |     xmlParserCtxtPtr    ctxt; /* the parser context */  | 
135  |  |     xmlSAXHandlerPtr    sax;  /* the parser SAX callbacks */  | 
136  |  |     xmlParserInputBufferPtr input;  /* the input */  | 
137  |  |     startElementSAXFunc   startElement;/* initial SAX callbacks */  | 
138  |  |     endElementSAXFunc   endElement;  /* idem */  | 
139  |  |     startElementNsSAX2Func  startElementNs;/* idem */  | 
140  |  |     endElementNsSAX2Func  endElementNs;  /* idem */  | 
141  |  |     charactersSAXFunc   characters;  | 
142  |  |     cdataBlockSAXFunc   cdataBlock;  | 
143  |  |     unsigned int    base; /* base of the segment in the input */  | 
144  |  |     unsigned int    cur;  /* current position in the input */  | 
145  |  |     xmlNodePtr      node; /* current node */  | 
146  |  |     xmlNodePtr      curnode;/* current attribute node */  | 
147  |  |     int       depth;  /* depth of the current node */  | 
148  |  |     xmlNodePtr      faketext;/* fake xmlNs chld */  | 
149  |  |     int       preserve;/* preserve the resulting document */  | 
150  |  |     xmlBufPtr           buffer; /* used to return const xmlChar * */  | 
151  |  |     xmlDictPtr      dict; /* the context dictionary */  | 
152  |  |  | 
153  |  |     /* entity stack when traversing entities content */  | 
154  |  |     xmlNodePtr         ent;          /* Current Entity Ref Node */  | 
155  |  |     int                entNr;        /* Depth of the entities stack */  | 
156  |  |     int                entMax;       /* Max depth of the entities stack */  | 
157  |  |     xmlNodePtr        *entTab;       /* array of entities */  | 
158  |  |  | 
159  |  |     /* error handling */  | 
160  |  |     xmlTextReaderErrorFunc errorFunc;    /* callback function */  | 
161  |  |     void                  *errorFuncArg; /* callback function user argument */  | 
162  |  |  | 
163  |  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
164  |  |     /* Handling of RelaxNG validation */  | 
165  |  |     xmlRelaxNGPtr          rngSchemas;  /* The Relax NG schemas */  | 
166  |  |     xmlRelaxNGValidCtxtPtr rngValidCtxt;/* The Relax NG validation context */  | 
167  |  |     int                    rngPreserveCtxt; /* 1 if the context was provided by the user */  | 
168  |  |     int                    rngValidErrors;/* The number of errors detected */  | 
169  |  |     xmlNodePtr             rngFullNode; /* the node if RNG not progressive */  | 
170  |  |     /* Handling of Schemas validation */  | 
171  |  |     xmlSchemaPtr          xsdSchemas; /* The Schemas schemas */  | 
172  |  |     xmlSchemaValidCtxtPtr xsdValidCtxt;/* The Schemas validation context */  | 
173  |  |     int                   xsdPreserveCtxt; /* 1 if the context was provided by the user */  | 
174  |  |     int                   xsdValidErrors;/* The number of errors detected */  | 
175  |  |     xmlSchemaSAXPlugPtr   xsdPlug;  /* the schemas plug in SAX pipeline */  | 
176  |  | #endif  | 
177  |  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
178  |  |     /* Handling of XInclude processing */  | 
179  |  |     int                xinclude;  /* is xinclude asked for */  | 
180  |  |     const xmlChar *    xinclude_name; /* the xinclude name from dict */  | 
181  |  |     xmlXIncludeCtxtPtr xincctxt;  /* the xinclude context */  | 
182  |  |     int                in_xinclude; /* counts for xinclude */  | 
183  |  | #endif  | 
184  |  | #ifdef LIBXML_PATTERN_ENABLED  | 
185  |  |     int                patternNr;       /* number of preserve patterns */  | 
186  |  |     int                patternMax;      /* max preserve patterns */  | 
187  |  |     xmlPatternPtr     *patternTab;      /* array of preserve patterns */  | 
188  |  | #endif  | 
189  |  |     int                preserves; /* level of preserves */  | 
190  |  |     int                parserFlags; /* the set of options set */  | 
191  |  |     /* Structured error handling */  | 
192  |  |     xmlStructuredErrorFunc sErrorFunc;  /* callback function */  | 
193  |  | };  | 
194  |  |  | 
195  | 4.97M  | #define NODE_IS_EMPTY   0x1  | 
196  | 16.0M  | #define NODE_IS_PRESERVED 0x2  | 
197  | 0  | #define NODE_IS_SPRESERVED  0x4  | 
198  |  |  | 
199  |  | /**  | 
200  |  |  * CONSTSTR:  | 
201  |  |  *  | 
202  |  |  * Macro used to return an interned string  | 
203  |  |  */  | 
204  | 0  | #define CONSTSTR(str) xmlDictLookup(reader->dict, (str), -1)  | 
205  | 0  | #define CONSTQSTR(p, str) xmlDictQLookup(reader->dict, (p), (str))  | 
206  |  |  | 
207  |  | static int xmlTextReaderReadTree(xmlTextReaderPtr reader);  | 
208  |  | static int xmlTextReaderNextTree(xmlTextReaderPtr reader);  | 
209  |  |  | 
210  |  | /************************************************************************  | 
211  |  |  *                  *  | 
212  |  |  *  Our own version of the freeing routines as we recycle nodes *  | 
213  |  |  *                  *  | 
214  |  |  ************************************************************************/  | 
215  |  | /**  | 
216  |  |  * DICT_FREE:  | 
217  |  |  * @str:  a string  | 
218  |  |  *  | 
219  |  |  * Free a string if it is not owned by the "dict" dictionary in the  | 
220  |  |  * current scope  | 
221  |  |  */  | 
222  |  | #define DICT_FREE(str)            \  | 
223  | 39.1M  |   if ((str) && ((!dict) ||       \  | 
224  | 38.5M  |       (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \  | 
225  | 28.4M  |       xmlFree((char *)(str));  | 
226  |  |  | 
227  |  | static void xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur);  | 
228  |  | static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur);  | 
229  |  |  | 
230  |  | /**  | 
231  |  |  * xmlTextReaderFreeProp:  | 
232  |  |  * @reader:  the xmlTextReaderPtr used  | 
233  |  |  * @cur:  the node  | 
234  |  |  *  | 
235  |  |  * Free a node.  | 
236  |  |  */  | 
237  |  | static void  | 
238  | 11.1M  | xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) { | 
239  | 11.1M  |     xmlDictPtr dict;  | 
240  |  |  | 
241  | 11.1M  |     if ((reader != NULL) && (reader->ctxt != NULL))  | 
242  | 11.1M  |   dict = reader->ctxt->dict;  | 
243  | 0  |     else  | 
244  | 0  |         dict = NULL;  | 
245  | 11.1M  |     if (cur == NULL) return;  | 
246  |  |  | 
247  | 11.1M  |     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))  | 
248  | 0  |   xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);  | 
249  |  |  | 
250  | 11.1M  |     if (cur->children != NULL)  | 
251  | 11.1M  |         xmlTextReaderFreeNodeList(reader, cur->children);  | 
252  |  |  | 
253  | 11.1M  |     DICT_FREE(cur->name);  | 
254  | 11.1M  |     if ((reader != NULL) && (reader->ctxt != NULL) &&  | 
255  | 11.1M  |         (reader->ctxt->freeAttrsNr < MAX_FREE_NODES)) { | 
256  | 485k  |         cur->next = reader->ctxt->freeAttrs;  | 
257  | 485k  |   reader->ctxt->freeAttrs = cur;  | 
258  | 485k  |   reader->ctxt->freeAttrsNr++;  | 
259  | 10.6M  |     } else { | 
260  | 10.6M  |   xmlFree(cur);  | 
261  | 10.6M  |     }  | 
262  | 11.1M  | }  | 
263  |  |  | 
264  |  | /**  | 
265  |  |  * xmlTextReaderFreePropList:  | 
266  |  |  * @reader:  the xmlTextReaderPtr used  | 
267  |  |  * @cur:  the first property in the list  | 
268  |  |  *  | 
269  |  |  * Free a property and all its siblings, all the children are freed too.  | 
270  |  |  */  | 
271  |  | static void  | 
272  | 6.61M  | xmlTextReaderFreePropList(xmlTextReaderPtr reader, xmlAttrPtr cur) { | 
273  | 6.61M  |     xmlAttrPtr next;  | 
274  |  |  | 
275  | 17.7M  |     while (cur != NULL) { | 
276  | 11.1M  |         next = cur->next;  | 
277  | 11.1M  |         xmlTextReaderFreeProp(reader, cur);  | 
278  | 11.1M  |   cur = next;  | 
279  | 11.1M  |     }  | 
280  | 6.61M  | }  | 
281  |  |  | 
282  |  | /**  | 
283  |  |  * xmlTextReaderFreeNodeList:  | 
284  |  |  * @reader:  the xmlTextReaderPtr used  | 
285  |  |  * @cur:  the first node in the list  | 
286  |  |  *  | 
287  |  |  * Free a node and all its siblings, this is a recursive behaviour, all  | 
288  |  |  * the children are freed too.  | 
289  |  |  */  | 
290  |  | static void  | 
291  | 11.3M  | xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) { | 
292  | 11.3M  |     xmlNodePtr next;  | 
293  | 11.3M  |     xmlNodePtr parent;  | 
294  | 11.3M  |     xmlDictPtr dict;  | 
295  | 11.3M  |     size_t depth = 0;  | 
296  |  |  | 
297  | 11.3M  |     if ((reader != NULL) && (reader->ctxt != NULL))  | 
298  | 11.3M  |   dict = reader->ctxt->dict;  | 
299  | 0  |     else  | 
300  | 0  |         dict = NULL;  | 
301  | 11.3M  |     if (cur == NULL) return;  | 
302  | 11.3M  |     if (cur->type == XML_NAMESPACE_DECL) { | 
303  | 0  |   xmlFreeNsList((xmlNsPtr) cur);  | 
304  | 0  |   return;  | 
305  | 0  |     }  | 
306  | 11.3M  |     if ((cur->type == XML_DOCUMENT_NODE) ||  | 
307  | 11.3M  |   (cur->type == XML_HTML_DOCUMENT_NODE)) { | 
308  | 0  |   xmlFreeDoc((xmlDocPtr) cur);  | 
309  | 0  |   return;  | 
310  | 0  |     }  | 
311  | 21.6M  |     while (1) { | 
312  | 23.3M  |         while ((cur->type != XML_DTD_NODE) &&  | 
313  | 23.3M  |                (cur->type != XML_ENTITY_REF_NODE) &&  | 
314  | 23.3M  |                (cur->children != NULL) &&  | 
315  | 23.3M  |                (cur->children->parent == cur)) { | 
316  | 1.68M  |             cur = cur->children;  | 
317  | 1.68M  |             depth += 1;  | 
318  | 1.68M  |         }  | 
319  |  |  | 
320  | 21.6M  |         next = cur->next;  | 
321  | 21.6M  |         parent = cur->parent;  | 
322  |  |  | 
323  |  |   /* unroll to speed up freeing the document */  | 
324  | 21.6M  |   if (cur->type != XML_DTD_NODE) { | 
325  |  |  | 
326  | 21.6M  |       if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))  | 
327  | 0  |     xmlDeregisterNodeDefaultValue(cur);  | 
328  |  |  | 
329  | 21.6M  |       if (((cur->type == XML_ELEMENT_NODE) ||  | 
330  | 21.6M  |      (cur->type == XML_XINCLUDE_START) ||  | 
331  | 21.6M  |      (cur->type == XML_XINCLUDE_END)) &&  | 
332  | 21.6M  |     (cur->properties != NULL))  | 
333  | 3.22M  |     xmlTextReaderFreePropList(reader, cur->properties);  | 
334  | 21.6M  |       if ((cur->content != (xmlChar *) &(cur->properties)) &&  | 
335  | 21.6M  |           (cur->type != XML_ELEMENT_NODE) &&  | 
336  | 21.6M  |     (cur->type != XML_XINCLUDE_START) &&  | 
337  | 21.6M  |     (cur->type != XML_XINCLUDE_END) &&  | 
338  | 21.6M  |     (cur->type != XML_ENTITY_REF_NODE)) { | 
339  | 9.85M  |     DICT_FREE(cur->content);  | 
340  | 9.85M  |       }  | 
341  | 21.6M  |       if (((cur->type == XML_ELEMENT_NODE) ||  | 
342  | 21.6M  |            (cur->type == XML_XINCLUDE_START) ||  | 
343  | 21.6M  |      (cur->type == XML_XINCLUDE_END)) &&  | 
344  | 21.6M  |     (cur->nsDef != NULL))  | 
345  | 262k  |     xmlFreeNsList(cur->nsDef);  | 
346  |  |  | 
347  |  |       /*  | 
348  |  |        * we don't free element names here they are interned now  | 
349  |  |        */  | 
350  | 21.6M  |       if ((cur->type != XML_TEXT_NODE) &&  | 
351  | 21.6M  |     (cur->type != XML_COMMENT_NODE))  | 
352  | 5.89M  |     DICT_FREE(cur->name);  | 
353  | 21.6M  |       if (((cur->type == XML_ELEMENT_NODE) ||  | 
354  | 21.6M  |      (cur->type == XML_TEXT_NODE)) &&  | 
355  | 21.6M  |           (reader != NULL) && (reader->ctxt != NULL) &&  | 
356  | 21.6M  |     (reader->ctxt->freeElemsNr < MAX_FREE_NODES)) { | 
357  | 223k  |           cur->next = reader->ctxt->freeElems;  | 
358  | 223k  |     reader->ctxt->freeElems = cur;  | 
359  | 223k  |     reader->ctxt->freeElemsNr++;  | 
360  | 21.4M  |       } else { | 
361  | 21.4M  |     xmlFree(cur);  | 
362  | 21.4M  |       }  | 
363  | 21.6M  |   }  | 
364  |  |  | 
365  | 21.6M  |         if (next != NULL) { | 
366  | 8.67M  |       cur = next;  | 
367  | 13.0M  |         } else { | 
368  | 13.0M  |             if ((depth == 0) || (parent == NULL))  | 
369  | 11.3M  |                 break;  | 
370  | 1.68M  |             depth -= 1;  | 
371  | 1.68M  |             cur = parent;  | 
372  | 1.68M  |             cur->children = NULL;  | 
373  | 1.68M  |         }  | 
374  | 21.6M  |     }  | 
375  | 11.3M  | }  | 
376  |  |  | 
377  |  | /**  | 
378  |  |  * xmlTextReaderFreeNode:  | 
379  |  |  * @reader:  the xmlTextReaderPtr used  | 
380  |  |  * @cur:  the node  | 
381  |  |  *  | 
382  |  |  * Free a node, this is a recursive behaviour, all the children are freed too.  | 
383  |  |  * This doesn't unlink the child from the list, use xmlUnlinkNode() first.  | 
384  |  |  */  | 
385  |  | static void  | 
386  | 16.0M  | xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) { | 
387  | 16.0M  |     xmlDictPtr dict;  | 
388  |  |  | 
389  | 16.0M  |     if ((reader != NULL) && (reader->ctxt != NULL))  | 
390  | 16.0M  |   dict = reader->ctxt->dict;  | 
391  | 0  |     else  | 
392  | 0  |         dict = NULL;  | 
393  | 16.0M  |     if (cur->type == XML_DTD_NODE) { | 
394  | 0  |   xmlFreeDtd((xmlDtdPtr) cur);  | 
395  | 0  |   return;  | 
396  | 0  |     }  | 
397  | 16.0M  |     if (cur->type == XML_NAMESPACE_DECL) { | 
398  | 0  |   xmlFreeNs((xmlNsPtr) cur);  | 
399  | 0  |         return;  | 
400  | 0  |     }  | 
401  | 16.0M  |     if (cur->type == XML_ATTRIBUTE_NODE) { | 
402  | 0  |   xmlTextReaderFreeProp(reader, (xmlAttrPtr) cur);  | 
403  | 0  |   return;  | 
404  | 0  |     }  | 
405  |  |  | 
406  | 16.0M  |     if ((cur->children != NULL) &&  | 
407  | 16.0M  |   (cur->type != XML_ENTITY_REF_NODE)) { | 
408  | 0  |   if (cur->children->parent == cur)  | 
409  | 0  |       xmlTextReaderFreeNodeList(reader, cur->children);  | 
410  | 0  |   cur->children = NULL;  | 
411  | 0  |     }  | 
412  |  |  | 
413  | 16.0M  |     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))  | 
414  | 0  |   xmlDeregisterNodeDefaultValue(cur);  | 
415  |  |  | 
416  | 16.0M  |     if (((cur->type == XML_ELEMENT_NODE) ||  | 
417  | 16.0M  |    (cur->type == XML_XINCLUDE_START) ||  | 
418  | 16.0M  |    (cur->type == XML_XINCLUDE_END)) &&  | 
419  | 16.0M  |   (cur->properties != NULL))  | 
420  | 3.39M  |   xmlTextReaderFreePropList(reader, cur->properties);  | 
421  | 16.0M  |     if ((cur->content != (xmlChar *) &(cur->properties)) &&  | 
422  | 16.0M  |         (cur->type != XML_ELEMENT_NODE) &&  | 
423  | 16.0M  |   (cur->type != XML_XINCLUDE_START) &&  | 
424  | 16.0M  |   (cur->type != XML_XINCLUDE_END) &&  | 
425  | 16.0M  |   (cur->type != XML_ENTITY_REF_NODE)) { | 
426  | 5.33M  |   DICT_FREE(cur->content);  | 
427  | 5.33M  |     }  | 
428  | 16.0M  |     if (((cur->type == XML_ELEMENT_NODE) ||  | 
429  | 16.0M  |    (cur->type == XML_XINCLUDE_START) ||  | 
430  | 16.0M  |    (cur->type == XML_XINCLUDE_END)) &&  | 
431  | 16.0M  |   (cur->nsDef != NULL))  | 
432  | 593k  |   xmlFreeNsList(cur->nsDef);  | 
433  |  |  | 
434  |  |     /*  | 
435  |  |      * we don't free names here they are interned now  | 
436  |  |      */  | 
437  | 16.0M  |     if ((cur->type != XML_TEXT_NODE) &&  | 
438  | 16.0M  |         (cur->type != XML_COMMENT_NODE))  | 
439  | 6.91M  |   DICT_FREE(cur->name);  | 
440  |  |  | 
441  | 16.0M  |     if (((cur->type == XML_ELEMENT_NODE) ||  | 
442  | 16.0M  |    (cur->type == XML_TEXT_NODE)) &&  | 
443  | 16.0M  |   (reader != NULL) && (reader->ctxt != NULL) &&  | 
444  | 16.0M  |   (reader->ctxt->freeElemsNr < MAX_FREE_NODES)) { | 
445  | 502k  |   cur->next = reader->ctxt->freeElems;  | 
446  | 502k  |   reader->ctxt->freeElems = cur;  | 
447  | 502k  |   reader->ctxt->freeElemsNr++;  | 
448  | 15.5M  |     } else { | 
449  | 15.5M  |   xmlFree(cur);  | 
450  | 15.5M  |     }  | 
451  | 16.0M  | }  | 
452  |  |  | 
453  |  | /**  | 
454  |  |  * xmlTextReaderFreeDoc:  | 
455  |  |  * @reader:  the xmlTextReaderPtr used  | 
456  |  |  * @cur:  pointer to the document  | 
457  |  |  *  | 
458  |  |  * Free up all the structures used by a document, tree included.  | 
459  |  |  */  | 
460  |  | static void  | 
461  | 331k  | xmlTextReaderFreeDoc(xmlTextReaderPtr reader, xmlDocPtr cur) { | 
462  | 331k  |     xmlDtdPtr extSubset, intSubset;  | 
463  |  |  | 
464  | 331k  |     if (cur == NULL) return;  | 
465  |  |  | 
466  | 331k  |     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))  | 
467  | 0  |   xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);  | 
468  |  |  | 
469  |  |     /*  | 
470  |  |      * Do this before freeing the children list to avoid ID lookups  | 
471  |  |      */  | 
472  | 331k  |     if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);  | 
473  | 331k  |     cur->ids = NULL;  | 
474  | 331k  |     if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);  | 
475  | 331k  |     cur->refs = NULL;  | 
476  | 331k  |     extSubset = cur->extSubset;  | 
477  | 331k  |     intSubset = cur->intSubset;  | 
478  | 331k  |     if (intSubset == extSubset)  | 
479  | 119k  |   extSubset = NULL;  | 
480  | 331k  |     if (extSubset != NULL) { | 
481  | 58.4k  |   xmlUnlinkNode((xmlNodePtr) cur->extSubset);  | 
482  | 58.4k  |   cur->extSubset = NULL;  | 
483  | 58.4k  |   xmlFreeDtd(extSubset);  | 
484  | 58.4k  |     }  | 
485  | 331k  |     if (intSubset != NULL) { | 
486  | 212k  |   xmlUnlinkNode((xmlNodePtr) cur->intSubset);  | 
487  | 212k  |   cur->intSubset = NULL;  | 
488  | 212k  |   xmlFreeDtd(intSubset);  | 
489  | 212k  |     }  | 
490  |  |  | 
491  | 331k  |     if (cur->children != NULL) xmlTextReaderFreeNodeList(reader, cur->children);  | 
492  |  |  | 
493  | 331k  |     if (cur->version != NULL) xmlFree((char *) cur->version);  | 
494  | 331k  |     if (cur->name != NULL) xmlFree((char *) cur->name);  | 
495  | 331k  |     if (cur->encoding != NULL) xmlFree((char *) cur->encoding);  | 
496  | 331k  |     if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);  | 
497  | 331k  |     if (cur->URL != NULL) xmlFree((char *) cur->URL);  | 
498  | 331k  |     if (cur->dict != NULL) xmlDictFree(cur->dict);  | 
499  |  |  | 
500  | 331k  |     xmlFree(cur);  | 
501  | 331k  | }  | 
502  |  |  | 
503  |  | /************************************************************************  | 
504  |  |  *                  *  | 
505  |  |  *      The reader core parser        *  | 
506  |  |  *                  *  | 
507  |  |  ************************************************************************/  | 
508  |  | #ifdef DEBUG_READER  | 
509  |  | static void  | 
510  |  | xmlTextReaderDebug(xmlTextReaderPtr reader) { | 
511  |  |     if ((reader == NULL) || (reader->ctxt == NULL)) { | 
512  |  |   fprintf(stderr, "xmlTextReader NULL\n");  | 
513  |  |   return;  | 
514  |  |     }  | 
515  |  |     fprintf(stderr, "xmlTextReader: state %d depth %d ",  | 
516  |  |       reader->state, reader->depth);  | 
517  |  |     if (reader->node == NULL) { | 
518  |  |   fprintf(stderr, "node = NULL\n");  | 
519  |  |     } else { | 
520  |  |   fprintf(stderr, "node %s\n", reader->node->name);  | 
521  |  |     }  | 
522  |  |     fprintf(stderr, "  input: base %d, cur %d, depth %d: ",  | 
523  |  |       reader->base, reader->cur, reader->ctxt->nodeNr);  | 
524  |  |     if (reader->input->buffer == NULL) { | 
525  |  |   fprintf(stderr, "buffer is NULL\n");  | 
526  |  |     } else { | 
527  |  | #ifdef LIBXML_DEBUG_ENABLED  | 
528  |  |   xmlDebugDumpString(stderr,  | 
529  |  |     &reader->input->buffer->content[reader->cur]);  | 
530  |  | #endif  | 
531  |  |   fprintf(stderr, "\n");  | 
532  |  |     }  | 
533  |  | }  | 
534  |  | #endif  | 
535  |  |  | 
536  |  | /**  | 
537  |  |  * xmlTextReaderEntPush:  | 
538  |  |  * @reader:  the xmlTextReaderPtr used  | 
539  |  |  * @value:  the entity reference node  | 
540  |  |  *  | 
541  |  |  * Pushes a new entity reference node on top of the entities stack  | 
542  |  |  *  | 
543  |  |  * Returns -1 in case of error, the index in the stack otherwise  | 
544  |  |  */  | 
545  |  | static int  | 
546  |  | xmlTextReaderEntPush(xmlTextReaderPtr reader, xmlNodePtr value)  | 
547  | 2.81M  | { | 
548  | 2.81M  |     if (reader->entNr >= reader->entMax) { | 
549  | 4.62k  |         size_t newSize = reader->entMax == 0 ? 10 : reader->entMax * 2;  | 
550  | 4.62k  |         xmlNodePtr *tmp;  | 
551  |  |  | 
552  | 4.62k  |         tmp = (xmlNodePtr *) xmlRealloc(reader->entTab,  | 
553  | 4.62k  |                                         newSize * sizeof(*tmp));  | 
554  | 4.62k  |         if (tmp == NULL) { | 
555  | 0  |             xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");  | 
556  | 0  |             return (-1);  | 
557  | 0  |         }  | 
558  | 4.62k  |         reader->entTab = tmp;  | 
559  | 4.62k  |         reader->entMax = newSize;  | 
560  | 4.62k  |     }  | 
561  | 2.81M  |     reader->entTab[reader->entNr] = value;  | 
562  | 2.81M  |     reader->ent = value;  | 
563  | 2.81M  |     return (reader->entNr++);  | 
564  | 2.81M  | }  | 
565  |  |  | 
566  |  | /**  | 
567  |  |  * xmlTextReaderEntPop:  | 
568  |  |  * @reader:  the xmlTextReaderPtr used  | 
569  |  |  *  | 
570  |  |  * Pops the top element entity from the entities stack  | 
571  |  |  *  | 
572  |  |  * Returns the entity just removed  | 
573  |  |  */  | 
574  |  | static xmlNodePtr  | 
575  |  | xmlTextReaderEntPop(xmlTextReaderPtr reader)  | 
576  | 2.81M  | { | 
577  | 2.81M  |     xmlNodePtr ret;  | 
578  |  |  | 
579  | 2.81M  |     if (reader->entNr <= 0)  | 
580  | 0  |         return (NULL);  | 
581  | 2.81M  |     reader->entNr--;  | 
582  | 2.81M  |     if (reader->entNr > 0)  | 
583  | 2.65M  |         reader->ent = reader->entTab[reader->entNr - 1];  | 
584  | 163k  |     else  | 
585  | 163k  |         reader->ent = NULL;  | 
586  | 2.81M  |     ret = reader->entTab[reader->entNr];  | 
587  | 2.81M  |     reader->entTab[reader->entNr] = NULL;  | 
588  | 2.81M  |     return (ret);  | 
589  | 2.81M  | }  | 
590  |  |  | 
591  |  | /**  | 
592  |  |  * xmlTextReaderStartElement:  | 
593  |  |  * @ctx: the user data (XML parser context)  | 
594  |  |  * @fullname:  The element name, including namespace prefix  | 
595  |  |  * @atts:  An array of name/value attributes pairs, NULL terminated  | 
596  |  |  *  | 
597  |  |  * called when an opening tag has been processed.  | 
598  |  |  */  | 
599  |  | static void  | 
600  |  | xmlTextReaderStartElement(void *ctx, const xmlChar *fullname,  | 
601  | 0  |                     const xmlChar **atts) { | 
602  | 0  |     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;  | 
603  | 0  |     xmlTextReaderPtr reader = ctxt->_private;  | 
604  |  | 
  | 
605  |  | #ifdef DEBUG_CALLBACKS  | 
606  |  |     printf("xmlTextReaderStartElement(%s)\n", fullname); | 
607  |  | #endif  | 
608  | 0  |     if ((reader != NULL) && (reader->startElement != NULL)) { | 
609  | 0  |   reader->startElement(ctx, fullname, atts);  | 
610  | 0  |   if ((ctxt->node != NULL) && (ctxt->input != NULL) &&  | 
611  | 0  |       (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&  | 
612  | 0  |       (ctxt->input->cur[1] == '>'))  | 
613  | 0  |       ctxt->node->extra = NODE_IS_EMPTY;  | 
614  | 0  |     }  | 
615  | 0  |     if (reader != NULL)  | 
616  | 0  |   reader->state = XML_TEXTREADER_ELEMENT;  | 
617  | 0  | }  | 
618  |  |  | 
619  |  | /**  | 
620  |  |  * xmlTextReaderEndElement:  | 
621  |  |  * @ctx: the user data (XML parser context)  | 
622  |  |  * @fullname:  The element name, including namespace prefix  | 
623  |  |  *  | 
624  |  |  * called when an ending tag has been processed.  | 
625  |  |  */  | 
626  |  | static void  | 
627  | 0  | xmlTextReaderEndElement(void *ctx, const xmlChar *fullname) { | 
628  | 0  |     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;  | 
629  | 0  |     xmlTextReaderPtr reader = ctxt->_private;  | 
630  |  | 
  | 
631  |  | #ifdef DEBUG_CALLBACKS  | 
632  |  |     printf("xmlTextReaderEndElement(%s)\n", fullname); | 
633  |  | #endif  | 
634  | 0  |     if ((reader != NULL) && (reader->endElement != NULL)) { | 
635  | 0  |   reader->endElement(ctx, fullname);  | 
636  | 0  |     }  | 
637  | 0  | }  | 
638  |  |  | 
639  |  | /**  | 
640  |  |  * xmlTextReaderStartElementNs:  | 
641  |  |  * @ctx: the user data (XML parser context)  | 
642  |  |  * @localname:  the local name of the element  | 
643  |  |  * @prefix:  the element namespace prefix if available  | 
644  |  |  * @URI:  the element namespace name if available  | 
645  |  |  * @nb_namespaces:  number of namespace definitions on that node  | 
646  |  |  * @namespaces:  pointer to the array of prefix/URI pairs namespace definitions  | 
647  |  |  * @nb_attributes:  the number of attributes on that node  | 
648  |  |  * nb_defaulted:  the number of defaulted attributes.  | 
649  |  |  * @attributes:  pointer to the array of (localname/prefix/URI/value/end)  | 
650  |  |  *               attribute values.  | 
651  |  |  *  | 
652  |  |  * called when an opening tag has been processed.  | 
653  |  |  */  | 
654  |  | static void  | 
655  |  | xmlTextReaderStartElementNs(void *ctx,  | 
656  |  |                       const xmlChar *localname,  | 
657  |  |           const xmlChar *prefix,  | 
658  |  |           const xmlChar *URI,  | 
659  |  |           int nb_namespaces,  | 
660  |  |           const xmlChar **namespaces,  | 
661  |  |           int nb_attributes,  | 
662  |  |           int nb_defaulted,  | 
663  |  |           const xmlChar **attributes)  | 
664  | 5.64M  | { | 
665  | 5.64M  |     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;  | 
666  | 5.64M  |     xmlTextReaderPtr reader = ctxt->_private;  | 
667  |  |  | 
668  |  | #ifdef DEBUG_CALLBACKS  | 
669  |  |     printf("xmlTextReaderStartElementNs(%s)\n", localname); | 
670  |  | #endif  | 
671  | 5.64M  |     if ((reader != NULL) && (reader->startElementNs != NULL)) { | 
672  | 5.64M  |   reader->startElementNs(ctx, localname, prefix, URI, nb_namespaces,  | 
673  | 5.64M  |                          namespaces, nb_attributes, nb_defaulted,  | 
674  | 5.64M  |              attributes);  | 
675  | 5.64M  |   if ((ctxt->node != NULL) && (ctxt->input != NULL) &&  | 
676  | 5.64M  |       (ctxt->input->cur != NULL) && (ctxt->input->cur[0] == '/') &&  | 
677  | 5.64M  |       (ctxt->input->cur[1] == '>'))  | 
678  | 2.17M  |       ctxt->node->extra = NODE_IS_EMPTY;  | 
679  | 5.64M  |     }  | 
680  | 5.64M  |     if (reader != NULL)  | 
681  | 5.64M  |   reader->state = XML_TEXTREADER_ELEMENT;  | 
682  | 5.64M  | }  | 
683  |  |  | 
684  |  | /**  | 
685  |  |  * xmlTextReaderEndElementNs:  | 
686  |  |  * @ctx: the user data (XML parser context)  | 
687  |  |  * @localname:  the local name of the element  | 
688  |  |  * @prefix:  the element namespace prefix if available  | 
689  |  |  * @URI:  the element namespace name if available  | 
690  |  |  *  | 
691  |  |  * called when an ending tag has been processed.  | 
692  |  |  */  | 
693  |  | static void  | 
694  |  | xmlTextReaderEndElementNs(void *ctx,  | 
695  |  |                           const xmlChar * localname,  | 
696  |  |                           const xmlChar * prefix,  | 
697  |  |               const xmlChar * URI)  | 
698  | 5.23M  | { | 
699  | 5.23M  |     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;  | 
700  | 5.23M  |     xmlTextReaderPtr reader = ctxt->_private;  | 
701  |  |  | 
702  |  | #ifdef DEBUG_CALLBACKS  | 
703  |  |     printf("xmlTextReaderEndElementNs(%s)\n", localname); | 
704  |  | #endif  | 
705  | 5.23M  |     if ((reader != NULL) && (reader->endElementNs != NULL)) { | 
706  | 5.23M  |   reader->endElementNs(ctx, localname, prefix, URI);  | 
707  | 5.23M  |     }  | 
708  | 5.23M  | }  | 
709  |  |  | 
710  |  |  | 
711  |  | /**  | 
712  |  |  * xmlTextReaderCharacters:  | 
713  |  |  * @ctx: the user data (XML parser context)  | 
714  |  |  * @ch:  a xmlChar string  | 
715  |  |  * @len: the number of xmlChar  | 
716  |  |  *  | 
717  |  |  * receiving some chars from the parser.  | 
718  |  |  */  | 
719  |  | static void  | 
720  |  | xmlTextReaderCharacters(void *ctx, const xmlChar *ch, int len)  | 
721  | 13.0M  | { | 
722  | 13.0M  |     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;  | 
723  | 13.0M  |     xmlTextReaderPtr reader = ctxt->_private;  | 
724  |  |  | 
725  |  | #ifdef DEBUG_CALLBACKS  | 
726  |  |     printf("xmlTextReaderCharacters()\n"); | 
727  |  | #endif  | 
728  | 13.0M  |     if ((reader != NULL) && (reader->characters != NULL)) { | 
729  | 13.0M  |   reader->characters(ctx, ch, len);  | 
730  | 13.0M  |     }  | 
731  | 13.0M  | }  | 
732  |  |  | 
733  |  | /**  | 
734  |  |  * xmlTextReaderCDataBlock:  | 
735  |  |  * @ctx: the user data (XML parser context)  | 
736  |  |  * @value:  The pcdata content  | 
737  |  |  * @len:  the block length  | 
738  |  |  *  | 
739  |  |  * called when a pcdata block has been parsed  | 
740  |  |  */  | 
741  |  | static void  | 
742  |  | xmlTextReaderCDataBlock(void *ctx, const xmlChar *ch, int len)  | 
743  | 44.0k  | { | 
744  | 44.0k  |     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;  | 
745  | 44.0k  |     xmlTextReaderPtr reader = ctxt->_private;  | 
746  |  |  | 
747  |  | #ifdef DEBUG_CALLBACKS  | 
748  |  |     printf("xmlTextReaderCDataBlock()\n"); | 
749  |  | #endif  | 
750  | 44.0k  |     if ((reader != NULL) && (reader->cdataBlock != NULL)) { | 
751  | 44.0k  |   reader->cdataBlock(ctx, ch, len);  | 
752  | 44.0k  |     }  | 
753  | 44.0k  | }  | 
754  |  |  | 
755  |  | /**  | 
756  |  |  * xmlTextReaderPushData:  | 
757  |  |  * @reader:  the xmlTextReaderPtr used  | 
758  |  |  *  | 
759  |  |  * Push data down the progressive parser until a significant callback  | 
760  |  |  * got raised.  | 
761  |  |  *  | 
762  |  |  * Returns -1 in case of failure, 0 otherwise  | 
763  |  |  */  | 
764  |  | static int  | 
765  | 1.01M  | xmlTextReaderPushData(xmlTextReaderPtr reader) { | 
766  | 1.01M  |     xmlBufPtr inbuf;  | 
767  | 1.01M  |     int val, s;  | 
768  | 1.01M  |     xmlTextReaderState oldstate;  | 
769  |  |  | 
770  | 1.01M  |     if ((reader->input == NULL) || (reader->input->buffer == NULL))  | 
771  | 0  |   return(-1);  | 
772  |  |  | 
773  | 1.01M  |     oldstate = reader->state;  | 
774  | 1.01M  |     reader->state = XML_TEXTREADER_NONE;  | 
775  | 1.01M  |     inbuf = reader->input->buffer;  | 
776  |  |  | 
777  | 2.76M  |     while (reader->state == XML_TEXTREADER_NONE) { | 
778  | 2.24M  |   if (xmlBufUse(inbuf) < reader->cur + CHUNK_SIZE) { | 
779  |  |       /*  | 
780  |  |        * Refill the buffer unless we are at the end of the stream  | 
781  |  |        */  | 
782  | 390k  |       if (reader->mode != XML_TEXTREADER_MODE_EOF) { | 
783  | 390k  |     val = xmlParserInputBufferRead(reader->input, 4096);  | 
784  | 390k  |     if ((val == 0) &&  | 
785  | 390k  |         (reader->input->readcallback == NULL)) { | 
786  | 390k  |         if (xmlBufUse(inbuf) == reader->cur) { | 
787  | 125k  |       reader->mode = XML_TEXTREADER_MODE_EOF;  | 
788  | 125k  |       reader->state = oldstate;  | 
789  | 125k  |         }  | 
790  | 390k  |     } else if (val < 0) { | 
791  | 0  |         reader->mode = XML_TEXTREADER_MODE_EOF;  | 
792  | 0  |         reader->state = oldstate;  | 
793  | 0  |         if ((oldstate != XML_TEXTREADER_START) ||  | 
794  | 0  |       (reader->ctxt->myDoc != NULL))  | 
795  | 0  |       return(val);  | 
796  | 0  |     } else if (val == 0) { | 
797  |  |         /* mark the end of the stream and process the remains */  | 
798  | 0  |         reader->mode = XML_TEXTREADER_MODE_EOF;  | 
799  | 0  |         break;  | 
800  | 0  |     }  | 
801  |  |  | 
802  | 390k  |       } else  | 
803  | 0  |     break;  | 
804  | 390k  |   }  | 
805  |  |   /*  | 
806  |  |    * parse by block of CHUNK_SIZE bytes, various tests show that  | 
807  |  |    * it's the best tradeoff at least on a 1.2GH Duron  | 
808  |  |    */  | 
809  | 2.24M  |   if (xmlBufUse(inbuf) >= reader->cur + CHUNK_SIZE) { | 
810  | 1.85M  |       val = xmlParseChunk(reader->ctxt,  | 
811  | 1.85M  |                  (const char *) xmlBufContent(inbuf) + reader->cur,  | 
812  | 1.85M  |                                 CHUNK_SIZE, 0);  | 
813  | 1.85M  |       reader->cur += CHUNK_SIZE;  | 
814  | 1.85M  |       if (val != 0)  | 
815  | 97.8k  |     reader->ctxt->wellFormed = 0;  | 
816  | 1.85M  |       if (reader->ctxt->wellFormed == 0)  | 
817  | 97.8k  |     break;  | 
818  | 1.85M  |   } else { | 
819  | 390k  |       s = xmlBufUse(inbuf) - reader->cur;  | 
820  | 390k  |       val = xmlParseChunk(reader->ctxt,  | 
821  | 390k  |      (const char *) xmlBufContent(inbuf) + reader->cur,  | 
822  | 390k  |               s, 0);  | 
823  | 390k  |       reader->cur += s;  | 
824  | 390k  |       if (val != 0)  | 
825  | 144k  |     reader->ctxt->wellFormed = 0;  | 
826  | 390k  |       break;  | 
827  | 390k  |   }  | 
828  | 2.24M  |     }  | 
829  |  |  | 
830  |  |     /*  | 
831  |  |      * Discard the consumed input when needed and possible  | 
832  |  |      */  | 
833  | 1.01M  |     if (reader->mode == XML_TEXTREADER_MODE_INTERACTIVE) { | 
834  | 885k  |         if (reader->input->readcallback != NULL) { | 
835  | 0  |       if ((reader->cur >= 4096) &&  | 
836  | 0  |     (xmlBufUse(inbuf) - reader->cur <= CHUNK_SIZE)) { | 
837  | 0  |     val = xmlBufShrink(inbuf, reader->cur);  | 
838  | 0  |     if (val >= 0) { | 
839  | 0  |         reader->cur -= val;  | 
840  | 0  |     }  | 
841  | 0  |       }  | 
842  | 0  |   }  | 
843  | 885k  |     }  | 
844  |  |  | 
845  |  |     /*  | 
846  |  |      * At the end of the stream signal that the work is done to the Push  | 
847  |  |      * parser.  | 
848  |  |      */  | 
849  | 125k  |     else if (reader->mode == XML_TEXTREADER_MODE_EOF) { | 
850  | 125k  |   if (reader->state != XML_TEXTREADER_DONE) { | 
851  | 125k  |       s = xmlBufUse(inbuf) - reader->cur;  | 
852  | 125k  |       val = xmlParseChunk(reader->ctxt,  | 
853  | 125k  |      (const char *) xmlBufContent(inbuf) + reader->cur,  | 
854  | 125k  |               s, 1);  | 
855  | 125k  |       reader->cur = xmlBufUse(inbuf);  | 
856  | 125k  |       reader->state  = XML_TEXTREADER_DONE;  | 
857  | 125k  |       if (val != 0) { | 
858  | 98.2k  |           if (reader->ctxt->wellFormed)  | 
859  | 0  |         reader->ctxt->wellFormed = 0;  | 
860  | 98.2k  |     else  | 
861  | 98.2k  |         return(-1);  | 
862  | 98.2k  |       }  | 
863  | 125k  |   }  | 
864  | 125k  |     }  | 
865  | 913k  |     reader->state = oldstate;  | 
866  | 913k  |     if (reader->ctxt->wellFormed == 0) { | 
867  | 239k  |   reader->mode = XML_TEXTREADER_MODE_EOF;  | 
868  | 239k  |         return(-1);  | 
869  | 239k  |     }  | 
870  |  |  | 
871  | 674k  |     return(0);  | 
872  | 913k  | }  | 
873  |  |  | 
874  |  | #ifdef LIBXML_REGEXP_ENABLED  | 
875  |  | /**  | 
876  |  |  * xmlTextReaderValidatePush:  | 
877  |  |  * @reader:  the xmlTextReaderPtr used  | 
878  |  |  *  | 
879  |  |  * Push the current node for validation  | 
880  |  |  */  | 
881  |  | static void  | 
882  | 3.61M  | xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED) { | 
883  | 3.61M  |     xmlNodePtr node = reader->node;  | 
884  |  |  | 
885  | 3.61M  | #ifdef LIBXML_VALID_ENABLED  | 
886  | 3.61M  |     if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&  | 
887  | 3.61M  |         (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) { | 
888  | 2.94M  |   if ((node->ns == NULL) || (node->ns->prefix == NULL)) { | 
889  | 2.49M  |       reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,  | 
890  | 2.49M  |             reader->ctxt->myDoc, node, node->name);  | 
891  | 2.49M  |   } else { | 
892  |  |       /* TODO use the BuildQName interface */  | 
893  | 454k  |       xmlChar *qname;  | 
894  |  |  | 
895  | 454k  |       qname = xmlStrdup(node->ns->prefix);  | 
896  | 454k  |       qname = xmlStrcat(qname, BAD_CAST ":");  | 
897  | 454k  |       qname = xmlStrcat(qname, node->name);  | 
898  | 454k  |       reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,  | 
899  | 454k  |             reader->ctxt->myDoc, node, qname);  | 
900  | 454k  |       if (qname != NULL)  | 
901  | 454k  |     xmlFree(qname);  | 
902  | 454k  |   }  | 
903  | 2.94M  |     }  | 
904  | 3.61M  | #endif /* LIBXML_VALID_ENABLED */  | 
905  | 3.61M  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
906  | 3.61M  |     if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&  | 
907  | 3.61M  |                (reader->rngValidCtxt != NULL)) { | 
908  | 0  |   int ret;  | 
909  |  | 
  | 
910  | 0  |   if (reader->rngFullNode != NULL) return;  | 
911  | 0  |   ret = xmlRelaxNGValidatePushElement(reader->rngValidCtxt,  | 
912  | 0  |                                       reader->ctxt->myDoc,  | 
913  | 0  |               node);  | 
914  | 0  |   if (ret == 0) { | 
915  |  |       /*  | 
916  |  |        * this element requires a full tree  | 
917  |  |        */  | 
918  | 0  |       node = xmlTextReaderExpand(reader);  | 
919  | 0  |       if (node == NULL) { | 
920  | 0  |           ret = -1;  | 
921  | 0  |       } else { | 
922  | 0  |     ret = xmlRelaxNGValidateFullElement(reader->rngValidCtxt,  | 
923  | 0  |                 reader->ctxt->myDoc,  | 
924  | 0  |                 node);  | 
925  | 0  |     reader->rngFullNode = node;  | 
926  | 0  |       }  | 
927  | 0  |   }  | 
928  | 0  |   if (ret != 1)  | 
929  | 0  |       reader->rngValidErrors++;  | 
930  | 0  |     }  | 
931  | 3.61M  | #endif  | 
932  | 3.61M  | }  | 
933  |  |  | 
934  |  | /**  | 
935  |  |  * xmlTextReaderValidateCData:  | 
936  |  |  * @reader:  the xmlTextReaderPtr used  | 
937  |  |  * @data:  pointer to the CData  | 
938  |  |  * @len:  length of the CData block in bytes.  | 
939  |  |  *  | 
940  |  |  * Push some CData for validation  | 
941  |  |  */  | 
942  |  | static void  | 
943  |  | xmlTextReaderValidateCData(xmlTextReaderPtr reader,  | 
944  | 8.15M  |                            const xmlChar *data, int len) { | 
945  | 8.15M  | #ifdef LIBXML_VALID_ENABLED  | 
946  | 8.15M  |     if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&  | 
947  | 8.15M  |         (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) { | 
948  | 7.76M  |   reader->ctxt->valid &= xmlValidatePushCData(&reader->ctxt->vctxt,  | 
949  | 7.76M  |                                               data, len);  | 
950  | 7.76M  |     }  | 
951  | 8.15M  | #endif /* LIBXML_VALID_ENABLED */  | 
952  | 8.15M  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
953  | 8.15M  |     if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&  | 
954  | 8.15M  |                (reader->rngValidCtxt != NULL)) { | 
955  | 0  |   int ret;  | 
956  |  | 
  | 
957  | 0  |   if (reader->rngFullNode != NULL) return;  | 
958  | 0  |   ret = xmlRelaxNGValidatePushCData(reader->rngValidCtxt, data, len);  | 
959  | 0  |   if (ret != 1)  | 
960  | 0  |       reader->rngValidErrors++;  | 
961  | 0  |     }  | 
962  | 8.15M  | #endif  | 
963  | 8.15M  | }  | 
964  |  |  | 
965  |  | /**  | 
966  |  |  * xmlTextReaderValidatePop:  | 
967  |  |  * @reader:  the xmlTextReaderPtr used  | 
968  |  |  *  | 
969  |  |  * Pop the current node from validation  | 
970  |  |  */  | 
971  |  | static void  | 
972  | 3.53M  | xmlTextReaderValidatePop(xmlTextReaderPtr reader) { | 
973  | 3.53M  |     xmlNodePtr node = reader->node;  | 
974  |  |  | 
975  | 3.53M  | #ifdef LIBXML_VALID_ENABLED  | 
976  | 3.53M  |     if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&  | 
977  | 3.53M  |         (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) { | 
978  | 2.87M  |   if ((node->ns == NULL) || (node->ns->prefix == NULL)) { | 
979  | 2.43M  |       reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,  | 
980  | 2.43M  |             reader->ctxt->myDoc, node, node->name);  | 
981  | 2.43M  |   } else { | 
982  |  |       /* TODO use the BuildQName interface */  | 
983  | 444k  |       xmlChar *qname;  | 
984  |  |  | 
985  | 444k  |       qname = xmlStrdup(node->ns->prefix);  | 
986  | 444k  |       qname = xmlStrcat(qname, BAD_CAST ":");  | 
987  | 444k  |       qname = xmlStrcat(qname, node->name);  | 
988  | 444k  |       reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,  | 
989  | 444k  |             reader->ctxt->myDoc, node, qname);  | 
990  | 444k  |       if (qname != NULL)  | 
991  | 444k  |     xmlFree(qname);  | 
992  | 444k  |   }  | 
993  | 2.87M  |     }  | 
994  | 3.53M  | #endif /* LIBXML_VALID_ENABLED */  | 
995  | 3.53M  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
996  | 3.53M  |     if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&  | 
997  | 3.53M  |                (reader->rngValidCtxt != NULL)) { | 
998  | 0  |   int ret;  | 
999  |  | 
  | 
1000  | 0  |   if (reader->rngFullNode != NULL) { | 
1001  | 0  |       if (node == reader->rngFullNode)  | 
1002  | 0  |           reader->rngFullNode = NULL;  | 
1003  | 0  |       return;  | 
1004  | 0  |   }  | 
1005  | 0  |   ret = xmlRelaxNGValidatePopElement(reader->rngValidCtxt,  | 
1006  | 0  |                                      reader->ctxt->myDoc,  | 
1007  | 0  |              node);  | 
1008  | 0  |   if (ret != 1)  | 
1009  | 0  |       reader->rngValidErrors++;  | 
1010  | 0  |     }  | 
1011  | 3.53M  | #endif  | 
1012  | 3.53M  | }  | 
1013  |  |  | 
1014  |  | /**  | 
1015  |  |  * xmlTextReaderValidateEntity:  | 
1016  |  |  * @reader:  the xmlTextReaderPtr used  | 
1017  |  |  *  | 
1018  |  |  * Handle the validation when an entity reference is encountered and  | 
1019  |  |  * entity substitution is not activated. As a result the parser interface  | 
1020  |  |  * must walk through the entity and do the validation calls  | 
1021  |  |  */  | 
1022  |  | static void  | 
1023  | 176k  | xmlTextReaderValidateEntity(xmlTextReaderPtr reader) { | 
1024  | 176k  |     xmlNodePtr oldnode = reader->node;  | 
1025  | 176k  |     xmlNodePtr node = reader->node;  | 
1026  |  |  | 
1027  | 12.3M  |     do { | 
1028  | 12.3M  |   if (node->type == XML_ENTITY_REF_NODE) { | 
1029  | 6.67M  |       if ((node->children != NULL) &&  | 
1030  | 6.67M  |     (node->children->type == XML_ENTITY_DECL) &&  | 
1031  | 6.67M  |     (node->children->children != NULL)) { | 
1032  | 2.81M  |     if (xmlTextReaderEntPush(reader, node) < 0) { | 
1033  | 0  |                     if (node == oldnode)  | 
1034  | 0  |                         break;  | 
1035  | 0  |                     goto skip_children;  | 
1036  | 0  |                 }  | 
1037  | 2.81M  |     node = node->children->children;  | 
1038  | 2.81M  |     continue;  | 
1039  | 3.85M  |       } else { | 
1040  |  |     /*  | 
1041  |  |      * The error has probably been raised already.  | 
1042  |  |      */  | 
1043  | 3.85M  |     if (node == oldnode)  | 
1044  | 13.1k  |         break;  | 
1045  | 3.83M  |                 goto skip_children;  | 
1046  | 3.85M  |       }  | 
1047  | 6.67M  | #ifdef LIBXML_REGEXP_ENABLED  | 
1048  | 6.67M  |   } else if (node->type == XML_ELEMENT_NODE) { | 
1049  | 740k  |       reader->node = node;  | 
1050  | 740k  |       xmlTextReaderValidatePush(reader);  | 
1051  | 4.93M  |   } else if ((node->type == XML_TEXT_NODE) ||  | 
1052  | 4.93M  |        (node->type == XML_CDATA_SECTION_NODE)) { | 
1053  | 4.36M  |             xmlTextReaderValidateCData(reader, node->content,  | 
1054  | 4.36M  |                                  xmlStrlen(node->content));  | 
1055  | 4.36M  | #endif  | 
1056  | 4.36M  |   }  | 
1057  |  |  | 
1058  |  |   /*  | 
1059  |  |    * go to next node  | 
1060  |  |    */  | 
1061  | 5.67M  |   if (node->children != NULL) { | 
1062  | 246k  |       node = node->children;  | 
1063  | 246k  |       continue;  | 
1064  | 5.42M  |   } else if (node->type == XML_ELEMENT_NODE) { | 
1065  | 494k  |       xmlTextReaderValidatePop(reader);  | 
1066  | 494k  |   }  | 
1067  | 9.26M  | skip_children:  | 
1068  | 9.26M  |   if (node->next != NULL) { | 
1069  | 6.62M  |       node = node->next;  | 
1070  | 6.62M  |       continue;  | 
1071  | 6.62M  |   }  | 
1072  | 3.06M  |   do { | 
1073  | 3.06M  |       node = node->parent;  | 
1074  | 3.06M  |       if (node->type == XML_ELEMENT_NODE) { | 
1075  | 246k  |           xmlNodePtr tmp;  | 
1076  | 246k  |     if (reader->entNr == 0) { | 
1077  | 0  |         while ((tmp = node->last) != NULL) { | 
1078  | 0  |       if ((tmp->extra & NODE_IS_PRESERVED) == 0) { | 
1079  | 0  |           xmlUnlinkNode(tmp);  | 
1080  | 0  |           xmlTextReaderFreeNode(reader, tmp);  | 
1081  | 0  |       } else  | 
1082  | 0  |           break;  | 
1083  | 0  |         }  | 
1084  | 0  |     }  | 
1085  | 246k  |     reader->node = node;  | 
1086  | 246k  |     xmlTextReaderValidatePop(reader);  | 
1087  | 246k  |       }  | 
1088  | 3.06M  |       if ((node->type == XML_ENTITY_DECL) &&  | 
1089  | 3.06M  |     (reader->ent != NULL) && (reader->ent->children == node)) { | 
1090  | 2.81M  |     node = xmlTextReaderEntPop(reader);  | 
1091  | 2.81M  |       }  | 
1092  | 3.06M  |       if (node == oldnode)  | 
1093  | 163k  |     break;  | 
1094  | 2.90M  |       if (node->next != NULL) { | 
1095  | 2.48M  |     node = node->next;  | 
1096  | 2.48M  |     break;  | 
1097  | 2.48M  |       }  | 
1098  | 2.90M  |   } while ((node != NULL) && (node != oldnode));  | 
1099  | 12.3M  |     } while ((node != NULL) && (node != oldnode));  | 
1100  | 176k  |     reader->node = oldnode;  | 
1101  | 176k  | }  | 
1102  |  | #endif /* LIBXML_REGEXP_ENABLED */  | 
1103  |  |  | 
1104  |  |  | 
1105  |  | /**  | 
1106  |  |  * xmlTextReaderGetSuccessor:  | 
1107  |  |  * @cur:  the current node  | 
1108  |  |  *  | 
1109  |  |  * Get the successor of a node if available.  | 
1110  |  |  *  | 
1111  |  |  * Returns the successor node or NULL  | 
1112  |  |  */  | 
1113  |  | static xmlNodePtr  | 
1114  | 2.73M  | xmlTextReaderGetSuccessor(xmlNodePtr cur) { | 
1115  | 2.73M  |     if (cur == NULL) return(NULL) ; /* ERROR */  | 
1116  | 2.73M  |     if (cur->next != NULL) return(cur->next) ;  | 
1117  | 3.91M  |     do { | 
1118  | 3.91M  |         cur = cur->parent;  | 
1119  | 3.91M  |         if (cur == NULL) break;  | 
1120  | 3.76M  |         if (cur->next != NULL) return(cur->next);  | 
1121  | 3.76M  |     } while (cur != NULL);  | 
1122  | 149k  |     return(cur);  | 
1123  | 2.62M  | }  | 
1124  |  |  | 
1125  |  | /**  | 
1126  |  |  * xmlTextReaderDoExpand:  | 
1127  |  |  * @reader:  the xmlTextReaderPtr used  | 
1128  |  |  *  | 
1129  |  |  * Makes sure that the current node is fully read as well as all its  | 
1130  |  |  * descendant. It means the full DOM subtree must be available at the  | 
1131  |  |  * end of the call.  | 
1132  |  |  *  | 
1133  |  |  * Returns 1 if the node was expanded successfully, 0 if there is no more  | 
1134  |  |  *          nodes to read, or -1 in case of error  | 
1135  |  |  */  | 
1136  |  | static int  | 
1137  | 3.03M  | xmlTextReaderDoExpand(xmlTextReaderPtr reader) { | 
1138  | 3.03M  |     int val;  | 
1139  |  |  | 
1140  | 3.03M  |     if ((reader == NULL) || (reader->node == NULL) || (reader->ctxt == NULL))  | 
1141  | 0  |         return(-1);  | 
1142  | 3.15M  |     do { | 
1143  | 3.15M  |   if (reader->ctxt->instate == XML_PARSER_EOF) return(1);  | 
1144  |  |  | 
1145  | 2.73M  |         if (xmlTextReaderGetSuccessor(reader->node) != NULL)  | 
1146  | 2.58M  |       return(1);  | 
1147  | 149k  |   if (reader->ctxt->nodeNr < reader->depth)  | 
1148  | 15.8k  |       return(1);  | 
1149  | 133k  |   if (reader->mode == XML_TEXTREADER_MODE_EOF)  | 
1150  | 0  |       return(1);  | 
1151  | 133k  |   val = xmlTextReaderPushData(reader);  | 
1152  | 133k  |   if (val < 0){ | 
1153  | 9.22k  |       reader->mode = XML_TEXTREADER_MODE_ERROR;  | 
1154  | 9.22k  |       return(-1);  | 
1155  | 9.22k  |   }  | 
1156  | 133k  |     } while(reader->mode != XML_TEXTREADER_MODE_EOF);  | 
1157  | 11  |     return(1);  | 
1158  | 3.03M  | }  | 
1159  |  |  | 
1160  |  | /**  | 
1161  |  |  * xmlTextReaderCollectSiblings:  | 
1162  |  |  * @node:    the first child  | 
1163  |  |  *  | 
1164  |  |  *  Traverse depth-first through all sibling nodes and their children  | 
1165  |  |  *  nodes and concatenate their content. This is an auxiliary function  | 
1166  |  |  *  to xmlTextReaderReadString.  | 
1167  |  |  *  | 
1168  |  |  *  Returns a string containing the content, or NULL in case of error.  | 
1169  |  |  */  | 
1170  |  | static xmlChar *  | 
1171  |  | xmlTextReaderCollectSiblings(xmlNodePtr node)  | 
1172  | 0  | { | 
1173  | 0  |     xmlBufferPtr buffer;  | 
1174  | 0  |     xmlChar *ret;  | 
1175  |  | 
  | 
1176  | 0  |     if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))  | 
1177  | 0  |         return(NULL);  | 
1178  |  |  | 
1179  | 0  |     buffer = xmlBufferCreate();  | 
1180  | 0  |     if (buffer == NULL)  | 
1181  | 0  |        return NULL;  | 
1182  | 0  |     xmlBufferSetAllocationScheme(buffer, XML_BUFFER_ALLOC_DOUBLEIT);  | 
1183  |  | 
  | 
1184  | 0  |     for ( ; node != NULL; node = node->next) { | 
1185  | 0  |        switch (node->type) { | 
1186  | 0  |        case XML_TEXT_NODE:  | 
1187  | 0  |        case XML_CDATA_SECTION_NODE:  | 
1188  | 0  |            xmlBufferCat(buffer, node->content);  | 
1189  | 0  |            break;  | 
1190  | 0  |        case XML_ELEMENT_NODE: { | 
1191  | 0  |            xmlChar *tmp;  | 
1192  |  | 
  | 
1193  | 0  |      tmp = xmlTextReaderCollectSiblings(node->children);  | 
1194  | 0  |            xmlBufferCat(buffer, tmp);  | 
1195  | 0  |      xmlFree(tmp);  | 
1196  | 0  |      break;  | 
1197  | 0  |        }  | 
1198  | 0  |        default:  | 
1199  | 0  |            break;  | 
1200  | 0  |        }  | 
1201  | 0  |     }  | 
1202  | 0  |     ret = buffer->content;  | 
1203  | 0  |     buffer->content = NULL;  | 
1204  | 0  |     xmlBufferFree(buffer);  | 
1205  | 0  |     return(ret);  | 
1206  | 0  | }  | 
1207  |  |  | 
1208  |  | /**  | 
1209  |  |  * xmlTextReaderRead:  | 
1210  |  |  * @reader:  the xmlTextReaderPtr used  | 
1211  |  |  *  | 
1212  |  |  *  Moves the position of the current instance to the next node in  | 
1213  |  |  *  the stream, exposing its properties.  | 
1214  |  |  *  | 
1215  |  |  *  Returns 1 if the node was read successfully, 0 if there is no more  | 
1216  |  |  *          nodes to read, or -1 in case of error  | 
1217  |  |  */  | 
1218  |  | int  | 
1219  | 21.3M  | xmlTextReaderRead(xmlTextReaderPtr reader) { | 
1220  | 21.3M  |     int val, olddepth = 0;  | 
1221  | 21.3M  |     xmlTextReaderState oldstate = XML_TEXTREADER_START;  | 
1222  | 21.3M  |     xmlNodePtr oldnode = NULL;  | 
1223  |  |  | 
1224  |  |  | 
1225  | 21.3M  |     if (reader == NULL)  | 
1226  | 0  |   return(-1);  | 
1227  | 21.3M  |     reader->curnode = NULL;  | 
1228  | 21.3M  |     if (reader->doc != NULL)  | 
1229  | 0  |         return(xmlTextReaderReadTree(reader));  | 
1230  | 21.3M  |     if (reader->ctxt == NULL)  | 
1231  | 0  |   return(-1);  | 
1232  |  |  | 
1233  |  | #ifdef DEBUG_READER  | 
1234  |  |     fprintf(stderr, "\nREAD ");  | 
1235  |  |     DUMP_READER  | 
1236  |  | #endif  | 
1237  | 21.3M  |     if (reader->mode == XML_TEXTREADER_MODE_INITIAL) { | 
1238  | 365k  |   reader->mode = XML_TEXTREADER_MODE_INTERACTIVE;  | 
1239  |  |   /*  | 
1240  |  |    * Initial state  | 
1241  |  |    */  | 
1242  | 459k  |   do { | 
1243  | 459k  |       val = xmlTextReaderPushData(reader);  | 
1244  | 459k  |     if (val < 0){ | 
1245  | 296k  |       reader->mode = XML_TEXTREADER_MODE_ERROR;  | 
1246  | 296k  |       reader->state = XML_TEXTREADER_ERROR;  | 
1247  | 296k  |     return(-1);  | 
1248  | 296k  |     }  | 
1249  | 459k  |   } while ((reader->ctxt->node == NULL) &&  | 
1250  | 163k  |      ((reader->mode != XML_TEXTREADER_MODE_EOF) &&  | 
1251  | 118k  |       (reader->state != XML_TEXTREADER_DONE)));  | 
1252  | 68.9k  |   if (reader->ctxt->node == NULL) { | 
1253  | 24.2k  |       if (reader->ctxt->myDoc != NULL) { | 
1254  | 24.2k  |     reader->node = reader->ctxt->myDoc->children;  | 
1255  | 24.2k  |       }  | 
1256  | 24.2k  |       if (reader->node == NULL){ | 
1257  | 0  |       reader->mode = XML_TEXTREADER_MODE_ERROR;  | 
1258  | 0  |       reader->state = XML_TEXTREADER_ERROR;  | 
1259  | 0  |     return(-1);  | 
1260  | 0  |     }  | 
1261  | 24.2k  |       reader->state = XML_TEXTREADER_ELEMENT;  | 
1262  | 44.7k  |   } else { | 
1263  | 44.7k  |       if (reader->ctxt->myDoc != NULL) { | 
1264  | 44.7k  |     reader->node = reader->ctxt->myDoc->children;  | 
1265  | 44.7k  |       }  | 
1266  | 44.7k  |       if (reader->node == NULL)  | 
1267  | 0  |     reader->node = reader->ctxt->nodeTab[0];  | 
1268  | 44.7k  |       reader->state = XML_TEXTREADER_ELEMENT;  | 
1269  | 44.7k  |   }  | 
1270  | 68.9k  |   reader->depth = 0;  | 
1271  | 68.9k  |   reader->ctxt->parseMode = XML_PARSE_READER;  | 
1272  | 68.9k  |   goto node_found;  | 
1273  | 68.9k  |     }  | 
1274  | 20.9M  |     oldstate = reader->state;  | 
1275  | 20.9M  |     olddepth = reader->ctxt->nodeNr;  | 
1276  | 20.9M  |     oldnode = reader->node;  | 
1277  |  |  | 
1278  | 20.9M  | get_next_node:  | 
1279  | 20.9M  |     if (reader->node == NULL) { | 
1280  | 0  |   if (reader->mode == XML_TEXTREADER_MODE_EOF)  | 
1281  | 0  |       return(0);  | 
1282  | 0  |   else  | 
1283  | 0  |       return(-1);  | 
1284  | 0  |     }  | 
1285  |  |  | 
1286  |  |     /*  | 
1287  |  |      * If we are not backtracking on ancestors or examined nodes,  | 
1288  |  |      * that the parser didn't finished or that we aren't at the end  | 
1289  |  |      * of stream, continue processing.  | 
1290  |  |      */  | 
1291  | 21.3M  |     while ((reader->node != NULL) && (reader->node->next == NULL) &&  | 
1292  | 21.3M  |      (reader->ctxt->nodeNr == olddepth) &&  | 
1293  | 21.3M  |            ((oldstate == XML_TEXTREADER_BACKTRACK) ||  | 
1294  | 4.98M  |             (reader->node->children == NULL) ||  | 
1295  | 4.98M  |       (reader->node->type == XML_ENTITY_REF_NODE) ||  | 
1296  | 4.98M  |       ((reader->node->children != NULL) &&  | 
1297  | 1.21M  |        (reader->node->children->type == XML_TEXT_NODE) &&  | 
1298  | 1.21M  |        (reader->node->children->next == NULL)) ||  | 
1299  | 4.98M  |       (reader->node->type == XML_DTD_NODE) ||  | 
1300  | 4.98M  |       (reader->node->type == XML_DOCUMENT_NODE) ||  | 
1301  | 4.98M  |       (reader->node->type == XML_HTML_DOCUMENT_NODE)) &&  | 
1302  | 21.3M  |      ((reader->ctxt->node == NULL) ||  | 
1303  | 4.18M  |       (reader->ctxt->node == reader->node) ||  | 
1304  | 4.18M  |       (reader->ctxt->node == reader->node->parent)) &&  | 
1305  | 21.3M  |      (reader->ctxt->instate != XML_PARSER_EOF)) { | 
1306  | 418k  |   val = xmlTextReaderPushData(reader);  | 
1307  | 418k  |   if (val < 0){ | 
1308  | 32.0k  |     reader->mode = XML_TEXTREADER_MODE_ERROR;  | 
1309  | 32.0k  |     reader->state = XML_TEXTREADER_ERROR;  | 
1310  | 32.0k  |       return(-1);  | 
1311  | 32.0k  |   }  | 
1312  | 386k  |   if (reader->node == NULL)  | 
1313  | 0  |       goto node_end;  | 
1314  | 386k  |     }  | 
1315  | 20.9M  |     if (oldstate != XML_TEXTREADER_BACKTRACK) { | 
1316  | 17.4M  |   if ((reader->node->children != NULL) &&  | 
1317  | 17.4M  |       (reader->node->type != XML_ENTITY_REF_NODE) &&  | 
1318  | 17.4M  |       (reader->node->type != XML_XINCLUDE_START) &&  | 
1319  | 17.4M  |       (reader->node->type != XML_DTD_NODE)) { | 
1320  | 3.57M  |       reader->node = reader->node->children;  | 
1321  | 3.57M  |       reader->depth++;  | 
1322  | 3.57M  |       reader->state = XML_TEXTREADER_ELEMENT;  | 
1323  | 3.57M  |       goto node_found;  | 
1324  | 3.57M  |   }  | 
1325  | 17.4M  |     }  | 
1326  | 17.3M  |     if (reader->node->next != NULL) { | 
1327  | 13.8M  |   if ((oldstate == XML_TEXTREADER_ELEMENT) &&  | 
1328  | 13.8M  |             (reader->node->type == XML_ELEMENT_NODE) &&  | 
1329  | 13.8M  |       (reader->node->children == NULL) &&  | 
1330  | 13.8M  |       ((reader->node->extra & NODE_IS_EMPTY) == 0)  | 
1331  | 13.8M  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
1332  | 13.8M  |       && (reader->in_xinclude <= 0)  | 
1333  | 13.8M  | #endif  | 
1334  | 13.8M  |       ) { | 
1335  | 1.22M  |       reader->state = XML_TEXTREADER_END;  | 
1336  | 1.22M  |       goto node_found;  | 
1337  | 1.22M  |   }  | 
1338  | 12.6M  | #ifdef LIBXML_REGEXP_ENABLED  | 
1339  | 12.6M  |   if ((reader->validate) &&  | 
1340  | 12.6M  |       (reader->node->type == XML_ELEMENT_NODE))  | 
1341  | 2.47M  |       xmlTextReaderValidatePop(reader);  | 
1342  | 12.6M  | #endif /* LIBXML_REGEXP_ENABLED */  | 
1343  | 12.6M  |         if ((reader->preserves > 0) &&  | 
1344  | 12.6M  |       (reader->node->extra & NODE_IS_SPRESERVED))  | 
1345  | 0  |       reader->preserves--;  | 
1346  | 12.6M  |   reader->node = reader->node->next;  | 
1347  | 12.6M  |   reader->state = XML_TEXTREADER_ELEMENT;  | 
1348  |  |  | 
1349  |  |   /*  | 
1350  |  |    * Cleanup of the old node  | 
1351  |  |    */  | 
1352  | 12.6M  |   if ((reader->preserves == 0) &&  | 
1353  | 12.6M  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
1354  | 12.6M  |       (reader->in_xinclude == 0) &&  | 
1355  | 12.6M  | #endif  | 
1356  | 12.6M  |       (reader->entNr == 0) &&  | 
1357  | 12.6M  |       (reader->node->prev != NULL) &&  | 
1358  | 12.6M  |             (reader->node->prev->type != XML_DTD_NODE)) { | 
1359  | 12.5M  |       xmlNodePtr tmp = reader->node->prev;  | 
1360  | 12.5M  |       if ((tmp->extra & NODE_IS_PRESERVED) == 0) { | 
1361  | 12.5M  |                 if (oldnode == tmp)  | 
1362  | 12.5M  |                     oldnode = NULL;  | 
1363  | 12.5M  |     xmlUnlinkNode(tmp);  | 
1364  | 12.5M  |     xmlTextReaderFreeNode(reader, tmp);  | 
1365  | 12.5M  |       }  | 
1366  | 12.5M  |   }  | 
1367  |  |  | 
1368  | 12.6M  |   goto node_found;  | 
1369  | 13.8M  |     }  | 
1370  | 3.53M  |     if ((oldstate == XML_TEXTREADER_ELEMENT) &&  | 
1371  | 3.53M  |   (reader->node->type == XML_ELEMENT_NODE) &&  | 
1372  | 3.53M  |   (reader->node->children == NULL) &&  | 
1373  | 3.53M  |   ((reader->node->extra & NODE_IS_EMPTY) == 0)) {; | 
1374  | 32.2k  |   reader->state = XML_TEXTREADER_END;  | 
1375  | 32.2k  |   goto node_found;  | 
1376  | 32.2k  |     }  | 
1377  | 3.49M  | #ifdef LIBXML_REGEXP_ENABLED  | 
1378  | 3.49M  |     if ((reader->validate != XML_TEXTREADER_NOT_VALIDATE) && (reader->node->type == XML_ELEMENT_NODE))  | 
1379  | 318k  |   xmlTextReaderValidatePop(reader);  | 
1380  | 3.49M  | #endif /* LIBXML_REGEXP_ENABLED */  | 
1381  | 3.49M  |     if ((reader->preserves > 0) &&  | 
1382  | 3.49M  |   (reader->node->extra & NODE_IS_SPRESERVED))  | 
1383  | 0  |   reader->preserves--;  | 
1384  | 3.49M  |     reader->node = reader->node->parent;  | 
1385  | 3.49M  |     if ((reader->node == NULL) ||  | 
1386  | 3.49M  |   (reader->node->type == XML_DOCUMENT_NODE) ||  | 
1387  | 3.49M  |   (reader->node->type == XML_HTML_DOCUMENT_NODE)) { | 
1388  | 27.7k  |   if (reader->mode != XML_TEXTREADER_MODE_EOF) { | 
1389  | 0  |       val = xmlParseChunk(reader->ctxt, "", 0, 1);  | 
1390  | 0  |       reader->state = XML_TEXTREADER_DONE;  | 
1391  | 0  |       if (val != 0)  | 
1392  | 0  |           return(-1);  | 
1393  | 0  |   }  | 
1394  | 27.7k  |   reader->node = NULL;  | 
1395  | 27.7k  |   reader->depth = -1;  | 
1396  |  |  | 
1397  |  |   /*  | 
1398  |  |    * Cleanup of the old node  | 
1399  |  |    */  | 
1400  | 27.7k  |   if ((oldnode != NULL) && (reader->preserves == 0) &&  | 
1401  | 27.7k  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
1402  | 27.7k  |       (reader->in_xinclude == 0) &&  | 
1403  | 27.7k  | #endif  | 
1404  | 27.7k  |       (reader->entNr == 0) &&  | 
1405  | 27.7k  |       (oldnode->type != XML_DTD_NODE) &&  | 
1406  | 27.7k  |       ((oldnode->extra & NODE_IS_PRESERVED) == 0)) { | 
1407  | 27.7k  |       xmlUnlinkNode(oldnode);  | 
1408  | 27.7k  |       xmlTextReaderFreeNode(reader, oldnode);  | 
1409  | 27.7k  |   }  | 
1410  |  |  | 
1411  | 27.7k  |   goto node_end;  | 
1412  | 27.7k  |     }  | 
1413  | 3.47M  |     if ((reader->preserves == 0) &&  | 
1414  | 3.47M  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
1415  | 3.47M  |         (reader->in_xinclude == 0) &&  | 
1416  | 3.47M  | #endif  | 
1417  | 3.47M  |   (reader->entNr == 0) &&  | 
1418  | 3.47M  |         (reader->node->last != NULL) &&  | 
1419  | 3.47M  |         ((reader->node->last->extra & NODE_IS_PRESERVED) == 0)) { | 
1420  | 3.47M  |   xmlNodePtr tmp = reader->node->last;  | 
1421  | 3.47M  |   xmlUnlinkNode(tmp);  | 
1422  | 3.47M  |   xmlTextReaderFreeNode(reader, tmp);  | 
1423  | 3.47M  |     }  | 
1424  | 3.47M  |     reader->depth--;  | 
1425  | 3.47M  |     reader->state = XML_TEXTREADER_BACKTRACK;  | 
1426  |  |  | 
1427  | 21.0M  | node_found:  | 
1428  | 21.0M  |     DUMP_READER  | 
1429  |  |  | 
1430  |  |     /*  | 
1431  |  |      * If we are in the middle of a piece of CDATA make sure it's finished  | 
1432  |  |      */  | 
1433  | 21.0M  |     if ((reader->node != NULL) &&  | 
1434  | 21.0M  |         (reader->node->next == NULL) &&  | 
1435  | 21.0M  |         ((reader->node->type == XML_TEXT_NODE) ||  | 
1436  | 5.08M  |    (reader->node->type == XML_CDATA_SECTION_NODE))) { | 
1437  | 3.03M  |             if (xmlTextReaderExpand(reader) == NULL)  | 
1438  | 9.22k  |           return -1;  | 
1439  | 3.03M  |     }  | 
1440  |  |  | 
1441  | 20.9M  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
1442  |  |     /*  | 
1443  |  |      * Handle XInclude if asked for  | 
1444  |  |      */  | 
1445  | 20.9M  |     if ((reader->xinclude) && (reader->in_xinclude == 0) &&  | 
1446  | 20.9M  |         (reader->node != NULL) &&  | 
1447  | 20.9M  |   (reader->node->type == XML_ELEMENT_NODE) &&  | 
1448  | 20.9M  |   (reader->node->ns != NULL) &&  | 
1449  | 20.9M  |   ((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) ||  | 
1450  | 0  |    (xmlStrEqual(reader->node->ns->href, XINCLUDE_OLD_NS)))) { | 
1451  | 0  |   if (reader->xincctxt == NULL) { | 
1452  | 0  |       reader->xincctxt = xmlXIncludeNewContext(reader->ctxt->myDoc);  | 
1453  | 0  |       xmlXIncludeSetFlags(reader->xincctxt,  | 
1454  | 0  |                           reader->parserFlags & (~XML_PARSE_NOXINCNODE));  | 
1455  | 0  |             xmlXIncludeSetStreamingMode(reader->xincctxt, 1);  | 
1456  | 0  |   }  | 
1457  |  |   /*  | 
1458  |  |    * expand that node and process it  | 
1459  |  |    */  | 
1460  | 0  |   if (xmlTextReaderExpand(reader) == NULL)  | 
1461  | 0  |       return -1;  | 
1462  | 0  |   xmlXIncludeProcessNode(reader->xincctxt, reader->node);  | 
1463  | 0  |     }  | 
1464  | 20.9M  |     if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_START)) { | 
1465  | 0  |         reader->in_xinclude++;  | 
1466  | 0  |   goto get_next_node;  | 
1467  | 0  |     }  | 
1468  | 20.9M  |     if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_END)) { | 
1469  | 0  |         reader->in_xinclude--;  | 
1470  | 0  |   goto get_next_node;  | 
1471  | 0  |     }  | 
1472  | 20.9M  | #endif  | 
1473  |  |     /*  | 
1474  |  |      * Handle entities enter and exit when in entity replacement mode  | 
1475  |  |      */  | 
1476  | 20.9M  |     if ((reader->node != NULL) &&  | 
1477  | 20.9M  |   (reader->node->type == XML_ENTITY_REF_NODE) &&  | 
1478  | 20.9M  |   (reader->ctxt != NULL) && (reader->ctxt->replaceEntities == 1)) { | 
1479  | 9.55k  |   if ((reader->node->children != NULL) &&  | 
1480  | 9.55k  |       (reader->node->children->type == XML_ENTITY_DECL) &&  | 
1481  | 9.55k  |       (reader->node->children->children != NULL)) { | 
1482  | 0  |       if (xmlTextReaderEntPush(reader, reader->node) < 0)  | 
1483  | 0  |                 goto get_next_node;  | 
1484  | 0  |       reader->node = reader->node->children->children;  | 
1485  | 0  |   }  | 
1486  | 9.55k  | #ifdef LIBXML_REGEXP_ENABLED  | 
1487  | 20.9M  |     } else if ((reader->node != NULL) &&  | 
1488  | 20.9M  |          (reader->node->type == XML_ENTITY_REF_NODE) &&  | 
1489  | 20.9M  |          (reader->ctxt != NULL) && (reader->validate)) { | 
1490  | 176k  |   xmlTextReaderValidateEntity(reader);  | 
1491  | 176k  | #endif /* LIBXML_REGEXP_ENABLED */  | 
1492  | 176k  |     }  | 
1493  | 20.9M  |     if ((reader->node != NULL) &&  | 
1494  | 20.9M  |   (reader->node->type == XML_ENTITY_DECL) &&  | 
1495  | 20.9M  |   (reader->ent != NULL) && (reader->ent->children == reader->node)) { | 
1496  | 0  |   reader->node = xmlTextReaderEntPop(reader);  | 
1497  | 0  |   reader->depth++;  | 
1498  | 0  |         goto get_next_node;  | 
1499  | 0  |     }  | 
1500  | 20.9M  | #ifdef LIBXML_REGEXP_ENABLED  | 
1501  | 20.9M  |     if ((reader->validate != XML_TEXTREADER_NOT_VALIDATE) && (reader->node != NULL)) { | 
1502  | 9.64M  |   xmlNodePtr node = reader->node;  | 
1503  |  |  | 
1504  | 9.64M  |   if ((node->type == XML_ELEMENT_NODE) &&  | 
1505  | 9.64M  |             ((reader->state != XML_TEXTREADER_END) &&  | 
1506  | 5.26M  |        (reader->state != XML_TEXTREADER_BACKTRACK))) { | 
1507  | 2.87M  |       xmlTextReaderValidatePush(reader);  | 
1508  | 6.76M  |   } else if ((node->type == XML_TEXT_NODE) ||  | 
1509  | 6.76M  |        (node->type == XML_CDATA_SECTION_NODE)) { | 
1510  | 3.79M  |             xmlTextReaderValidateCData(reader, node->content,  | 
1511  | 3.79M  |                                  xmlStrlen(node->content));  | 
1512  | 3.79M  |   }  | 
1513  | 9.64M  |     }  | 
1514  | 20.9M  | #endif /* LIBXML_REGEXP_ENABLED */  | 
1515  | 20.9M  | #ifdef LIBXML_PATTERN_ENABLED  | 
1516  | 20.9M  |     if ((reader->patternNr > 0) && (reader->state != XML_TEXTREADER_END) &&  | 
1517  | 20.9M  |         (reader->state != XML_TEXTREADER_BACKTRACK)) { | 
1518  | 0  |         int i;  | 
1519  | 0  |   for (i = 0;i < reader->patternNr;i++) { | 
1520  | 0  |        if (xmlPatternMatch(reader->patternTab[i], reader->node) == 1) { | 
1521  | 0  |            xmlTextReaderPreserve(reader);  | 
1522  | 0  |      break;  | 
1523  | 0  |              }  | 
1524  | 0  |   }  | 
1525  | 0  |     }  | 
1526  | 20.9M  | #endif /* LIBXML_PATTERN_ENABLED */  | 
1527  | 20.9M  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
1528  | 20.9M  |     if ((reader->validate == XML_TEXTREADER_VALIDATE_XSD) &&  | 
1529  | 20.9M  |         (reader->xsdValidErrors == 0) &&  | 
1530  | 20.9M  |   (reader->xsdValidCtxt != NULL)) { | 
1531  | 0  |   reader->xsdValidErrors = !xmlSchemaIsValid(reader->xsdValidCtxt);  | 
1532  | 0  |     }  | 
1533  | 20.9M  | #endif /* LIBXML_PATTERN_ENABLED */  | 
1534  | 20.9M  |     return(1);  | 
1535  | 27.7k  | node_end:  | 
1536  | 27.7k  |     reader->state = XML_TEXTREADER_DONE;  | 
1537  | 27.7k  |     return(0);  | 
1538  | 20.9M  | }  | 
1539  |  |  | 
1540  |  | /**  | 
1541  |  |  * xmlTextReaderReadState:  | 
1542  |  |  * @reader:  the xmlTextReaderPtr used  | 
1543  |  |  *  | 
1544  |  |  * Gets the read state of the reader.  | 
1545  |  |  *  | 
1546  |  |  * Returns the state value, or -1 in case of error  | 
1547  |  |  */  | 
1548  |  | int  | 
1549  | 0  | xmlTextReaderReadState(xmlTextReaderPtr reader) { | 
1550  | 0  |     if (reader == NULL)  | 
1551  | 0  |   return(-1);  | 
1552  | 0  |     return(reader->mode);  | 
1553  | 0  | }  | 
1554  |  |  | 
1555  |  | /**  | 
1556  |  |  * xmlTextReaderExpand:  | 
1557  |  |  * @reader:  the xmlTextReaderPtr used  | 
1558  |  |  *  | 
1559  |  |  * Reads the contents of the current node and the full subtree. It then makes  | 
1560  |  |  * the subtree available until the next xmlTextReaderRead() call  | 
1561  |  |  *  | 
1562  |  |  * Returns a node pointer valid until the next xmlTextReaderRead() call  | 
1563  |  |  *         or NULL in case of error.  | 
1564  |  |  */  | 
1565  |  | xmlNodePtr  | 
1566  | 3.03M  | xmlTextReaderExpand(xmlTextReaderPtr reader) { | 
1567  | 3.03M  |     if ((reader == NULL) || (reader->node == NULL))  | 
1568  | 0  |         return(NULL);  | 
1569  | 3.03M  |     if (reader->doc != NULL)  | 
1570  | 0  |         return(reader->node);  | 
1571  | 3.03M  |     if (reader->ctxt == NULL)  | 
1572  | 0  |         return(NULL);  | 
1573  | 3.03M  |     if (xmlTextReaderDoExpand(reader) < 0)  | 
1574  | 9.22k  |         return(NULL);  | 
1575  | 3.02M  |     return(reader->node);  | 
1576  | 3.03M  | }  | 
1577  |  |  | 
1578  |  | /**  | 
1579  |  |  * xmlTextReaderNext:  | 
1580  |  |  * @reader:  the xmlTextReaderPtr used  | 
1581  |  |  *  | 
1582  |  |  * Skip to the node following the current one in document order while  | 
1583  |  |  * avoiding the subtree if any.  | 
1584  |  |  *  | 
1585  |  |  * Returns 1 if the node was read successfully, 0 if there is no more  | 
1586  |  |  *          nodes to read, or -1 in case of error  | 
1587  |  |  */  | 
1588  |  | int  | 
1589  | 0  | xmlTextReaderNext(xmlTextReaderPtr reader) { | 
1590  | 0  |     int ret;  | 
1591  | 0  |     xmlNodePtr cur;  | 
1592  |  | 
  | 
1593  | 0  |     if (reader == NULL)  | 
1594  | 0  |   return(-1);  | 
1595  | 0  |     if (reader->doc != NULL)  | 
1596  | 0  |         return(xmlTextReaderNextTree(reader));  | 
1597  | 0  |     cur = reader->node;  | 
1598  | 0  |     if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))  | 
1599  | 0  |         return(xmlTextReaderRead(reader));  | 
1600  | 0  |     if (reader->state == XML_TEXTREADER_END || reader->state == XML_TEXTREADER_BACKTRACK)  | 
1601  | 0  |         return(xmlTextReaderRead(reader));  | 
1602  | 0  |     if (cur->extra & NODE_IS_EMPTY)  | 
1603  | 0  |         return(xmlTextReaderRead(reader));  | 
1604  | 0  |     do { | 
1605  | 0  |         ret = xmlTextReaderRead(reader);  | 
1606  | 0  |   if (ret != 1)  | 
1607  | 0  |       return(ret);  | 
1608  | 0  |     } while (reader->node != cur);  | 
1609  | 0  |     return(xmlTextReaderRead(reader));  | 
1610  | 0  | }  | 
1611  |  |  | 
1612  |  | #ifdef LIBXML_WRITER_ENABLED  | 
1613  |  | /**  | 
1614  |  |  * xmlTextReaderReadInnerXml:  | 
1615  |  |  * @reader:  the xmlTextReaderPtr used  | 
1616  |  |  *  | 
1617  |  |  * Reads the contents of the current node, including child nodes and markup.  | 
1618  |  |  *  | 
1619  |  |  * Returns a string containing the XML content, or NULL if the current node  | 
1620  |  |  *         is neither an element nor attribute, or has no child nodes. The  | 
1621  |  |  *         string must be deallocated by the caller.  | 
1622  |  |  */  | 
1623  |  | xmlChar *  | 
1624  |  | xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)  | 
1625  | 0  | { | 
1626  | 0  |     xmlChar *resbuf;  | 
1627  | 0  |     xmlNodePtr node, cur_node;  | 
1628  | 0  |     xmlBufferPtr buff, buff2;  | 
1629  | 0  |     xmlDocPtr doc;  | 
1630  |  | 
  | 
1631  | 0  |     if (xmlTextReaderExpand(reader) == NULL) { | 
1632  | 0  |         return NULL;  | 
1633  | 0  |     }  | 
1634  | 0  |     doc = reader->node->doc;  | 
1635  | 0  |     buff = xmlBufferCreate();  | 
1636  | 0  |     if (buff == NULL)  | 
1637  | 0  |         return NULL;  | 
1638  | 0  |     xmlBufferSetAllocationScheme(buff, XML_BUFFER_ALLOC_DOUBLEIT);  | 
1639  | 0  |     for (cur_node = reader->node->children; cur_node != NULL;  | 
1640  | 0  |          cur_node = cur_node->next) { | 
1641  |  |         /* XXX: Why is the node copied? */  | 
1642  | 0  |         node = xmlDocCopyNode(cur_node, doc, 1);  | 
1643  |  |         /* XXX: Why do we need a second buffer? */  | 
1644  | 0  |         buff2 = xmlBufferCreate();  | 
1645  | 0  |         xmlBufferSetAllocationScheme(buff2, XML_BUFFER_ALLOC_DOUBLEIT);  | 
1646  | 0  |         if (xmlNodeDump(buff2, doc, node, 0, 0) == -1) { | 
1647  | 0  |             xmlFreeNode(node);  | 
1648  | 0  |             xmlBufferFree(buff2);  | 
1649  | 0  |             xmlBufferFree(buff);  | 
1650  | 0  |             return NULL;  | 
1651  | 0  |         }  | 
1652  | 0  |         xmlBufferCat(buff, buff2->content);  | 
1653  | 0  |         xmlFreeNode(node);  | 
1654  | 0  |         xmlBufferFree(buff2);  | 
1655  | 0  |     }  | 
1656  | 0  |     resbuf = buff->content;  | 
1657  | 0  |     buff->content = NULL;  | 
1658  |  | 
  | 
1659  | 0  |     xmlBufferFree(buff);  | 
1660  | 0  |     return resbuf;  | 
1661  | 0  | }  | 
1662  |  | #endif  | 
1663  |  |  | 
1664  |  | #ifdef LIBXML_WRITER_ENABLED  | 
1665  |  | /**  | 
1666  |  |  * xmlTextReaderReadOuterXml:  | 
1667  |  |  * @reader:  the xmlTextReaderPtr used  | 
1668  |  |  *  | 
1669  |  |  * Reads the contents of the current node, including child nodes and markup.  | 
1670  |  |  *  | 
1671  |  |  * Returns a string containing the node and any XML content, or NULL if the  | 
1672  |  |  *         current node cannot be serialized. The string must be deallocated  | 
1673  |  |  *         by the caller.  | 
1674  |  |  */  | 
1675  |  | xmlChar *  | 
1676  |  | xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)  | 
1677  | 0  | { | 
1678  | 0  |     xmlChar *resbuf;  | 
1679  | 0  |     xmlNodePtr node;  | 
1680  | 0  |     xmlBufferPtr buff;  | 
1681  | 0  |     xmlDocPtr doc;  | 
1682  |  | 
  | 
1683  | 0  |     if (xmlTextReaderExpand(reader) == NULL) { | 
1684  | 0  |         return NULL;  | 
1685  | 0  |     }  | 
1686  | 0  |     node = reader->node;  | 
1687  | 0  |     doc = node->doc;  | 
1688  |  |     /* XXX: Why is the node copied? */  | 
1689  | 0  |   if (node->type == XML_DTD_NODE) { | 
1690  | 0  |     node = (xmlNodePtr) xmlCopyDtd((xmlDtdPtr) node);  | 
1691  | 0  |   } else { | 
1692  | 0  |     node = xmlDocCopyNode(node, doc, 1);  | 
1693  | 0  |   }  | 
1694  | 0  |     buff = xmlBufferCreate();  | 
1695  | 0  |     xmlBufferSetAllocationScheme(buff, XML_BUFFER_ALLOC_DOUBLEIT);  | 
1696  | 0  |     if (xmlNodeDump(buff, doc, node, 0, 0) == -1) { | 
1697  | 0  |         xmlFreeNode(node);  | 
1698  | 0  |         xmlBufferFree(buff);  | 
1699  | 0  |         return NULL;  | 
1700  | 0  |     }  | 
1701  |  |  | 
1702  | 0  |     resbuf = buff->content;  | 
1703  | 0  |     buff->content = NULL;  | 
1704  |  | 
  | 
1705  | 0  |     xmlFreeNode(node);  | 
1706  | 0  |     xmlBufferFree(buff);  | 
1707  | 0  |     return resbuf;  | 
1708  | 0  | }  | 
1709  |  | #endif  | 
1710  |  |  | 
1711  |  | /**  | 
1712  |  |  * xmlTextReaderReadString:  | 
1713  |  |  * @reader:  the xmlTextReaderPtr used  | 
1714  |  |  *  | 
1715  |  |  * Reads the contents of an element or a text node as a string.  | 
1716  |  |  *  | 
1717  |  |  * Returns a string containing the contents of the Element or Text node,  | 
1718  |  |  *         or NULL if the reader is positioned on any other type of node.  | 
1719  |  |  *         The string must be deallocated by the caller.  | 
1720  |  |  */  | 
1721  |  | xmlChar *  | 
1722  |  | xmlTextReaderReadString(xmlTextReaderPtr reader)  | 
1723  | 0  | { | 
1724  | 0  |     xmlNodePtr node;  | 
1725  |  | 
  | 
1726  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
1727  | 0  |        return(NULL);  | 
1728  |  |  | 
1729  | 0  |     node = (reader->curnode != NULL) ? reader->curnode : reader->node;  | 
1730  | 0  |     switch (node->type) { | 
1731  | 0  |     case XML_TEXT_NODE:  | 
1732  | 0  |        if (node->content != NULL)  | 
1733  | 0  |            return(xmlStrdup(node->content));  | 
1734  | 0  |        break;  | 
1735  | 0  |     case XML_ELEMENT_NODE:  | 
1736  | 0  |   if (xmlTextReaderDoExpand(reader) != -1) { | 
1737  | 0  |       return xmlTextReaderCollectSiblings(node->children);  | 
1738  | 0  |   }  | 
1739  | 0  |   break;  | 
1740  | 0  |     case XML_ATTRIBUTE_NODE:  | 
1741  | 0  |   TODO  | 
1742  | 0  |   break;  | 
1743  | 0  |     default:  | 
1744  | 0  |        break;  | 
1745  | 0  |     }  | 
1746  | 0  |     return(NULL);  | 
1747  | 0  | }  | 
1748  |  |  | 
1749  |  | #if 0  | 
1750  |  | /**  | 
1751  |  |  * xmlTextReaderReadBase64:  | 
1752  |  |  * @reader:  the xmlTextReaderPtr used  | 
1753  |  |  * @array:  a byte array to store the content.  | 
1754  |  |  * @offset:  the zero-based index into array where the method should  | 
1755  |  |  *           begin to write.  | 
1756  |  |  * @len:  the number of bytes to write.  | 
1757  |  |  *  | 
1758  |  |  * Reads and decodes the Base64 encoded contents of an element and  | 
1759  |  |  * stores the result in a byte buffer.  | 
1760  |  |  *  | 
1761  |  |  * Returns the number of bytes written to array, or zero if the current  | 
1762  |  |  *         instance is not positioned on an element or -1 in case of error.  | 
1763  |  |  */  | 
1764  |  | int  | 
1765  |  | xmlTextReaderReadBase64(xmlTextReaderPtr reader,  | 
1766  |  |                         unsigned char *array ATTRIBUTE_UNUSED,  | 
1767  |  |                   int offset ATTRIBUTE_UNUSED,  | 
1768  |  |       int len ATTRIBUTE_UNUSED) { | 
1769  |  |     if ((reader == NULL) || (reader->ctxt == NULL))  | 
1770  |  |   return(-1);  | 
1771  |  |     if (reader->ctxt->wellFormed != 1)  | 
1772  |  |   return(-1);  | 
1773  |  |  | 
1774  |  |     if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))  | 
1775  |  |   return(0);  | 
1776  |  |     TODO  | 
1777  |  |     return(0);  | 
1778  |  | }  | 
1779  |  |  | 
1780  |  | /**  | 
1781  |  |  * xmlTextReaderReadBinHex:  | 
1782  |  |  * @reader:  the xmlTextReaderPtr used  | 
1783  |  |  * @array:  a byte array to store the content.  | 
1784  |  |  * @offset:  the zero-based index into array where the method should  | 
1785  |  |  *           begin to write.  | 
1786  |  |  * @len:  the number of bytes to write.  | 
1787  |  |  *  | 
1788  |  |  * Reads and decodes the BinHex encoded contents of an element and  | 
1789  |  |  * stores the result in a byte buffer.  | 
1790  |  |  *  | 
1791  |  |  * Returns the number of bytes written to array, or zero if the current  | 
1792  |  |  *         instance is not positioned on an element or -1 in case of error.  | 
1793  |  |  */  | 
1794  |  | int  | 
1795  |  | xmlTextReaderReadBinHex(xmlTextReaderPtr reader,  | 
1796  |  |                         unsigned char *array ATTRIBUTE_UNUSED,  | 
1797  |  |                   int offset ATTRIBUTE_UNUSED,  | 
1798  |  |       int len ATTRIBUTE_UNUSED) { | 
1799  |  |     if ((reader == NULL) || (reader->ctxt == NULL))  | 
1800  |  |   return(-1);  | 
1801  |  |     if (reader->ctxt->wellFormed != 1)  | 
1802  |  |   return(-1);  | 
1803  |  |  | 
1804  |  |     if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE))  | 
1805  |  |   return(0);  | 
1806  |  |     TODO  | 
1807  |  |     return(0);  | 
1808  |  | }  | 
1809  |  | #endif  | 
1810  |  |  | 
1811  |  | /************************************************************************  | 
1812  |  |  *                  *  | 
1813  |  |  *      Operating on a preparsed tree     *  | 
1814  |  |  *                  *  | 
1815  |  |  ************************************************************************/  | 
1816  |  | static int  | 
1817  |  | xmlTextReaderNextTree(xmlTextReaderPtr reader)  | 
1818  | 0  | { | 
1819  | 0  |     if (reader == NULL)  | 
1820  | 0  |         return(-1);  | 
1821  |  |  | 
1822  | 0  |     if (reader->state == XML_TEXTREADER_END)  | 
1823  | 0  |         return(0);  | 
1824  |  |  | 
1825  | 0  |     if (reader->node == NULL) { | 
1826  | 0  |         if (reader->doc->children == NULL) { | 
1827  | 0  |             reader->state = XML_TEXTREADER_END;  | 
1828  | 0  |             return(0);  | 
1829  | 0  |         }  | 
1830  |  |  | 
1831  | 0  |         reader->node = reader->doc->children;  | 
1832  | 0  |         reader->state = XML_TEXTREADER_START;  | 
1833  | 0  |         return(1);  | 
1834  | 0  |     }  | 
1835  |  |  | 
1836  | 0  |     if (reader->state != XML_TEXTREADER_BACKTRACK) { | 
1837  |  |   /* Here removed traversal to child, because we want to skip the subtree,  | 
1838  |  |   replace with traversal to sibling to skip subtree */  | 
1839  | 0  |         if (reader->node->next != 0) { | 
1840  |  |       /* Move to sibling if present,skipping sub-tree */  | 
1841  | 0  |             reader->node = reader->node->next;  | 
1842  | 0  |             reader->state = XML_TEXTREADER_START;  | 
1843  | 0  |             return(1);  | 
1844  | 0  |         }  | 
1845  |  |  | 
1846  |  |   /* if reader->node->next is NULL mean no subtree for current node,  | 
1847  |  |   so need to move to sibling of parent node if present */  | 
1848  | 0  |   reader->state = XML_TEXTREADER_BACKTRACK;  | 
1849  |  |   /* This will move to parent if present */  | 
1850  | 0  |   xmlTextReaderRead(reader);  | 
1851  | 0  |     }  | 
1852  |  |  | 
1853  | 0  |     if (reader->node->next != 0) { | 
1854  | 0  |         reader->node = reader->node->next;  | 
1855  | 0  |         reader->state = XML_TEXTREADER_START;  | 
1856  | 0  |         return(1);  | 
1857  | 0  |     }  | 
1858  |  |  | 
1859  | 0  |     if (reader->node->parent != 0) { | 
1860  | 0  |         if (reader->node->parent->type == XML_DOCUMENT_NODE) { | 
1861  | 0  |             reader->state = XML_TEXTREADER_END;  | 
1862  | 0  |             return(0);  | 
1863  | 0  |         }  | 
1864  |  |  | 
1865  | 0  |         reader->node = reader->node->parent;  | 
1866  | 0  |         reader->depth--;  | 
1867  | 0  |         reader->state = XML_TEXTREADER_BACKTRACK;  | 
1868  |  |   /* Repeat process to move to sibling of parent node if present */  | 
1869  | 0  |         xmlTextReaderNextTree(reader);  | 
1870  | 0  |     }  | 
1871  |  |  | 
1872  | 0  |     reader->state = XML_TEXTREADER_END;  | 
1873  |  | 
  | 
1874  | 0  |     return(1);  | 
1875  | 0  | }  | 
1876  |  |  | 
1877  |  | /**  | 
1878  |  |  * xmlTextReaderReadTree:  | 
1879  |  |  * @reader:  the xmlTextReaderPtr used  | 
1880  |  |  *  | 
1881  |  |  *  Moves the position of the current instance to the next node in  | 
1882  |  |  *  the stream, exposing its properties.  | 
1883  |  |  *  | 
1884  |  |  *  Returns 1 if the node was read successfully, 0 if there is no more  | 
1885  |  |  *          nodes to read, or -1 in case of error  | 
1886  |  |  */  | 
1887  |  | static int  | 
1888  | 0  | xmlTextReaderReadTree(xmlTextReaderPtr reader) { | 
1889  | 0  |     if (reader->state == XML_TEXTREADER_END)  | 
1890  | 0  |         return(0);  | 
1891  |  |  | 
1892  | 0  | next_node:  | 
1893  | 0  |     if (reader->node == NULL) { | 
1894  | 0  |         if (reader->doc->children == NULL) { | 
1895  | 0  |             reader->state = XML_TEXTREADER_END;  | 
1896  | 0  |             return(0);  | 
1897  | 0  |         }  | 
1898  |  |  | 
1899  | 0  |         reader->node = reader->doc->children;  | 
1900  | 0  |         reader->state = XML_TEXTREADER_START;  | 
1901  | 0  |         goto found_node;  | 
1902  | 0  |     }  | 
1903  |  |  | 
1904  | 0  |     if ((reader->state != XML_TEXTREADER_BACKTRACK) &&  | 
1905  | 0  |         (reader->node->type != XML_DTD_NODE) &&  | 
1906  | 0  |         (reader->node->type != XML_XINCLUDE_START) &&  | 
1907  | 0  |   (reader->node->type != XML_ENTITY_REF_NODE)) { | 
1908  | 0  |         if (reader->node->children != NULL) { | 
1909  | 0  |             reader->node = reader->node->children;  | 
1910  | 0  |             reader->depth++;  | 
1911  | 0  |             reader->state = XML_TEXTREADER_START;  | 
1912  | 0  |             goto found_node;  | 
1913  | 0  |         }  | 
1914  |  |  | 
1915  | 0  |         if (reader->node->type == XML_ATTRIBUTE_NODE) { | 
1916  | 0  |             reader->state = XML_TEXTREADER_BACKTRACK;  | 
1917  | 0  |             goto found_node;  | 
1918  | 0  |         }  | 
1919  | 0  |     }  | 
1920  |  |  | 
1921  | 0  |     if (reader->node->next != NULL) { | 
1922  | 0  |         reader->node = reader->node->next;  | 
1923  | 0  |         reader->state = XML_TEXTREADER_START;  | 
1924  | 0  |         goto found_node;  | 
1925  | 0  |     }  | 
1926  |  |  | 
1927  | 0  |     if (reader->node->parent != NULL) { | 
1928  | 0  |         if ((reader->node->parent->type == XML_DOCUMENT_NODE) ||  | 
1929  | 0  |       (reader->node->parent->type == XML_HTML_DOCUMENT_NODE)) { | 
1930  | 0  |             reader->state = XML_TEXTREADER_END;  | 
1931  | 0  |             return(0);  | 
1932  | 0  |         }  | 
1933  |  |  | 
1934  | 0  |         reader->node = reader->node->parent;  | 
1935  | 0  |         reader->depth--;  | 
1936  | 0  |         reader->state = XML_TEXTREADER_BACKTRACK;  | 
1937  | 0  |         goto found_node;  | 
1938  | 0  |     }  | 
1939  |  |  | 
1940  | 0  |     reader->state = XML_TEXTREADER_END;  | 
1941  |  | 
  | 
1942  | 0  | found_node:  | 
1943  | 0  |     if ((reader->node->type == XML_XINCLUDE_START) ||  | 
1944  | 0  |         (reader->node->type == XML_XINCLUDE_END))  | 
1945  | 0  |   goto next_node;  | 
1946  |  |  | 
1947  | 0  |     return(1);  | 
1948  | 0  | }  | 
1949  |  |  | 
1950  |  | /**  | 
1951  |  |  * xmlTextReaderNextSibling:  | 
1952  |  |  * @reader:  the xmlTextReaderPtr used  | 
1953  |  |  *  | 
1954  |  |  * Skip to the node following the current one in document order while  | 
1955  |  |  * avoiding the subtree if any.  | 
1956  |  |  * Currently implemented only for Readers built on a document  | 
1957  |  |  *  | 
1958  |  |  * Returns 1 if the node was read successfully, 0 if there is no more  | 
1959  |  |  *          nodes to read, or -1 in case of error  | 
1960  |  |  */  | 
1961  |  | int  | 
1962  | 0  | xmlTextReaderNextSibling(xmlTextReaderPtr reader) { | 
1963  | 0  |     if (reader == NULL)  | 
1964  | 0  |         return(-1);  | 
1965  | 0  |     if (reader->doc == NULL) { | 
1966  |  |         /* TODO */  | 
1967  | 0  |   return(-1);  | 
1968  | 0  |     }  | 
1969  |  |  | 
1970  | 0  |     if (reader->state == XML_TEXTREADER_END)  | 
1971  | 0  |         return(0);  | 
1972  |  |  | 
1973  | 0  |     if (reader->node == NULL)  | 
1974  | 0  |         return(xmlTextReaderNextTree(reader));  | 
1975  |  |  | 
1976  | 0  |     if (reader->node->next != NULL) { | 
1977  | 0  |         reader->node = reader->node->next;  | 
1978  | 0  |         reader->state = XML_TEXTREADER_START;  | 
1979  | 0  |         return(1);  | 
1980  | 0  |     }  | 
1981  |  |  | 
1982  | 0  |     return(0);  | 
1983  | 0  | }  | 
1984  |  |  | 
1985  |  | /************************************************************************  | 
1986  |  |  *                  *  | 
1987  |  |  *      Constructor and destructors     *  | 
1988  |  |  *                  *  | 
1989  |  |  ************************************************************************/  | 
1990  |  | /**  | 
1991  |  |  * xmlNewTextReader:  | 
1992  |  |  * @input: the xmlParserInputBufferPtr used to read data  | 
1993  |  |  * @URI: the URI information for the source if available  | 
1994  |  |  *  | 
1995  |  |  * Create an xmlTextReader structure fed with @input  | 
1996  |  |  *  | 
1997  |  |  * Returns the new xmlTextReaderPtr or NULL in case of error  | 
1998  |  |  */  | 
1999  |  | xmlTextReaderPtr  | 
2000  | 365k  | xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) { | 
2001  | 365k  |     xmlTextReaderPtr ret;  | 
2002  |  |  | 
2003  | 365k  |     if (input == NULL)  | 
2004  | 0  |   return(NULL);  | 
2005  | 365k  |     ret = xmlMalloc(sizeof(xmlTextReader));  | 
2006  | 365k  |     if (ret == NULL) { | 
2007  | 0  |         xmlGenericError(xmlGenericErrorContext,  | 
2008  | 0  |     "xmlNewTextReader : malloc failed\n");  | 
2009  | 0  |   return(NULL);  | 
2010  | 0  |     }  | 
2011  | 365k  |     memset(ret, 0, sizeof(xmlTextReader));  | 
2012  | 365k  |     ret->doc = NULL;  | 
2013  | 365k  |     ret->entTab = NULL;  | 
2014  | 365k  |     ret->entMax = 0;  | 
2015  | 365k  |     ret->entNr = 0;  | 
2016  | 365k  |     ret->input = input;  | 
2017  | 365k  |     ret->buffer = xmlBufCreateSize(100);  | 
2018  | 365k  |     if (ret->buffer == NULL) { | 
2019  | 0  |         xmlFree(ret);  | 
2020  | 0  |         xmlGenericError(xmlGenericErrorContext,  | 
2021  | 0  |     "xmlNewTextReader : malloc failed\n");  | 
2022  | 0  |   return(NULL);  | 
2023  | 0  |     }  | 
2024  |  |     /* no operation on a reader should require a huge buffer */  | 
2025  | 365k  |     xmlBufSetAllocationScheme(ret->buffer,  | 
2026  | 365k  |             XML_BUFFER_ALLOC_DOUBLEIT);  | 
2027  | 365k  |     ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));  | 
2028  | 365k  |     if (ret->sax == NULL) { | 
2029  | 0  |   xmlBufFree(ret->buffer);  | 
2030  | 0  |   xmlFree(ret);  | 
2031  | 0  |         xmlGenericError(xmlGenericErrorContext,  | 
2032  | 0  |     "xmlNewTextReader : malloc failed\n");  | 
2033  | 0  |   return(NULL);  | 
2034  | 0  |     }  | 
2035  | 365k  |     xmlSAXVersion(ret->sax, 2);  | 
2036  | 365k  |     ret->startElement = ret->sax->startElement;  | 
2037  | 365k  |     ret->sax->startElement = xmlTextReaderStartElement;  | 
2038  | 365k  |     ret->endElement = ret->sax->endElement;  | 
2039  | 365k  |     ret->sax->endElement = xmlTextReaderEndElement;  | 
2040  | 365k  | #ifdef LIBXML_SAX1_ENABLED  | 
2041  | 365k  |     if (ret->sax->initialized == XML_SAX2_MAGIC) { | 
2042  | 365k  | #endif /* LIBXML_SAX1_ENABLED */  | 
2043  | 365k  |   ret->startElementNs = ret->sax->startElementNs;  | 
2044  | 365k  |   ret->sax->startElementNs = xmlTextReaderStartElementNs;  | 
2045  | 365k  |   ret->endElementNs = ret->sax->endElementNs;  | 
2046  | 365k  |   ret->sax->endElementNs = xmlTextReaderEndElementNs;  | 
2047  | 365k  | #ifdef LIBXML_SAX1_ENABLED  | 
2048  | 365k  |     } else { | 
2049  | 0  |   ret->startElementNs = NULL;  | 
2050  | 0  |   ret->endElementNs = NULL;  | 
2051  | 0  |     }  | 
2052  | 365k  | #endif /* LIBXML_SAX1_ENABLED */  | 
2053  | 365k  |     ret->characters = ret->sax->characters;  | 
2054  | 365k  |     ret->sax->characters = xmlTextReaderCharacters;  | 
2055  | 365k  |     ret->sax->ignorableWhitespace = xmlTextReaderCharacters;  | 
2056  | 365k  |     ret->cdataBlock = ret->sax->cdataBlock;  | 
2057  | 365k  |     ret->sax->cdataBlock = xmlTextReaderCDataBlock;  | 
2058  |  |  | 
2059  | 365k  |     ret->mode = XML_TEXTREADER_MODE_INITIAL;  | 
2060  | 365k  |     ret->node = NULL;  | 
2061  | 365k  |     ret->curnode = NULL;  | 
2062  | 365k  |     if (xmlBufUse(ret->input->buffer) < 4) { | 
2063  | 10.3k  |   xmlParserInputBufferRead(input, 4);  | 
2064  | 10.3k  |     }  | 
2065  | 365k  |     if (xmlBufUse(ret->input->buffer) >= 4) { | 
2066  | 354k  |   ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL,  | 
2067  | 354k  |            (const char *) xmlBufContent(ret->input->buffer),  | 
2068  | 354k  |                                             4, URI);  | 
2069  | 354k  |   ret->base = 0;  | 
2070  | 354k  |   ret->cur = 4;  | 
2071  | 354k  |     } else { | 
2072  | 10.3k  |   ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL, NULL, 0, URI);  | 
2073  | 10.3k  |   ret->base = 0;  | 
2074  | 10.3k  |   ret->cur = 0;  | 
2075  | 10.3k  |     }  | 
2076  |  |  | 
2077  | 365k  |     if (ret->ctxt == NULL) { | 
2078  | 0  |         xmlGenericError(xmlGenericErrorContext,  | 
2079  | 0  |     "xmlNewTextReader : malloc failed\n");  | 
2080  | 0  |   xmlBufFree(ret->buffer);  | 
2081  | 0  |   xmlFree(ret->sax);  | 
2082  | 0  |   xmlFree(ret);  | 
2083  | 0  |   return(NULL);  | 
2084  | 0  |     }  | 
2085  | 365k  |     ret->ctxt->parseMode = XML_PARSE_READER;  | 
2086  | 365k  |     ret->ctxt->_private = ret;  | 
2087  | 365k  |     ret->ctxt->linenumbers = 1;  | 
2088  | 365k  |     ret->ctxt->dictNames = 1;  | 
2089  | 365k  |     ret->allocs = XML_TEXTREADER_CTXT;  | 
2090  |  |     /*  | 
2091  |  |      * use the parser dictionary to allocate all elements and attributes names  | 
2092  |  |      */  | 
2093  | 365k  |     ret->ctxt->docdict = 1;  | 
2094  | 365k  |     ret->dict = ret->ctxt->dict;  | 
2095  | 365k  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
2096  | 365k  |     ret->xinclude = 0;  | 
2097  | 365k  | #endif  | 
2098  | 365k  | #ifdef LIBXML_PATTERN_ENABLED  | 
2099  | 365k  |     ret->patternMax = 0;  | 
2100  | 365k  |     ret->patternTab = NULL;  | 
2101  | 365k  | #endif  | 
2102  | 365k  |     return(ret);  | 
2103  | 365k  | }  | 
2104  |  |  | 
2105  |  | /**  | 
2106  |  |  * xmlNewTextReaderFilename:  | 
2107  |  |  * @URI: the URI of the resource to process  | 
2108  |  |  *  | 
2109  |  |  * Create an xmlTextReader structure fed with the resource at @URI  | 
2110  |  |  *  | 
2111  |  |  * Returns the new xmlTextReaderPtr or NULL in case of error  | 
2112  |  |  */  | 
2113  |  | xmlTextReaderPtr  | 
2114  | 0  | xmlNewTextReaderFilename(const char *URI) { | 
2115  | 0  |     xmlParserInputBufferPtr input;  | 
2116  | 0  |     xmlTextReaderPtr ret;  | 
2117  | 0  |     char *directory = NULL;  | 
2118  |  | 
  | 
2119  | 0  |     input = xmlParserInputBufferCreateFilename(URI, XML_CHAR_ENCODING_NONE);  | 
2120  | 0  |     if (input == NULL)  | 
2121  | 0  |   return(NULL);  | 
2122  | 0  |     ret = xmlNewTextReader(input, URI);  | 
2123  | 0  |     if (ret == NULL) { | 
2124  | 0  |   xmlFreeParserInputBuffer(input);  | 
2125  | 0  |   return(NULL);  | 
2126  | 0  |     }  | 
2127  | 0  |     ret->allocs |= XML_TEXTREADER_INPUT;  | 
2128  | 0  |     if (ret->ctxt->directory == NULL)  | 
2129  | 0  |         directory = xmlParserGetDirectory(URI);  | 
2130  | 0  |     if ((ret->ctxt->directory == NULL) && (directory != NULL))  | 
2131  | 0  |         ret->ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);  | 
2132  | 0  |     if (directory != NULL)  | 
2133  | 0  |   xmlFree(directory);  | 
2134  | 0  |     return(ret);  | 
2135  | 0  | }  | 
2136  |  |  | 
2137  |  | /**  | 
2138  |  |  * xmlFreeTextReader:  | 
2139  |  |  * @reader:  the xmlTextReaderPtr  | 
2140  |  |  *  | 
2141  |  |  * Deallocate all the resources associated to the reader  | 
2142  |  |  */  | 
2143  |  | void  | 
2144  | 365k  | xmlFreeTextReader(xmlTextReaderPtr reader) { | 
2145  | 365k  |     if (reader == NULL)  | 
2146  | 0  |   return;  | 
2147  | 365k  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
2148  | 365k  |     if (reader->rngSchemas != NULL) { | 
2149  | 0  |   xmlRelaxNGFree(reader->rngSchemas);  | 
2150  | 0  |   reader->rngSchemas = NULL;  | 
2151  | 0  |     }  | 
2152  | 365k  |     if (reader->rngValidCtxt != NULL) { | 
2153  | 0  |   if (! reader->rngPreserveCtxt)  | 
2154  | 0  |       xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);  | 
2155  | 0  |   reader->rngValidCtxt = NULL;  | 
2156  | 0  |     }  | 
2157  | 365k  |     if (reader->xsdPlug != NULL) { | 
2158  | 0  |   xmlSchemaSAXUnplug(reader->xsdPlug);  | 
2159  | 0  |   reader->xsdPlug = NULL;  | 
2160  | 0  |     }  | 
2161  | 365k  |     if (reader->xsdValidCtxt != NULL) { | 
2162  | 0  |   if (! reader->xsdPreserveCtxt)  | 
2163  | 0  |       xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);  | 
2164  | 0  |   reader->xsdValidCtxt = NULL;  | 
2165  | 0  |     }  | 
2166  | 365k  |     if (reader->xsdSchemas != NULL) { | 
2167  | 0  |   xmlSchemaFree(reader->xsdSchemas);  | 
2168  | 0  |   reader->xsdSchemas = NULL;  | 
2169  | 0  |     }  | 
2170  | 365k  | #endif  | 
2171  | 365k  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
2172  | 365k  |     if (reader->xincctxt != NULL)  | 
2173  | 0  |   xmlXIncludeFreeContext(reader->xincctxt);  | 
2174  | 365k  | #endif  | 
2175  | 365k  | #ifdef LIBXML_PATTERN_ENABLED  | 
2176  | 365k  |     if (reader->patternTab != NULL) { | 
2177  | 0  |         int i;  | 
2178  | 0  |   for (i = 0;i < reader->patternNr;i++) { | 
2179  | 0  |       if (reader->patternTab[i] != NULL)  | 
2180  | 0  |           xmlFreePattern(reader->patternTab[i]);  | 
2181  | 0  |   }  | 
2182  | 0  |   xmlFree(reader->patternTab);  | 
2183  | 0  |     }  | 
2184  | 365k  | #endif  | 
2185  | 365k  |     if (reader->mode != XML_TEXTREADER_MODE_CLOSED)  | 
2186  | 365k  |         xmlTextReaderClose(reader);  | 
2187  | 365k  |     if (reader->ctxt != NULL) { | 
2188  | 365k  |         if (reader->dict == reader->ctxt->dict)  | 
2189  | 365k  |       reader->dict = NULL;  | 
2190  | 365k  |   if (reader->allocs & XML_TEXTREADER_CTXT)  | 
2191  | 365k  |       xmlFreeParserCtxt(reader->ctxt);  | 
2192  | 365k  |     }  | 
2193  | 365k  |     if (reader->sax != NULL)  | 
2194  | 365k  |   xmlFree(reader->sax);  | 
2195  | 365k  |     if (reader->buffer != NULL)  | 
2196  | 365k  |         xmlBufFree(reader->buffer);  | 
2197  | 365k  |     if (reader->entTab != NULL)  | 
2198  | 4.61k  |   xmlFree(reader->entTab);  | 
2199  | 365k  |     if (reader->dict != NULL)  | 
2200  | 0  |         xmlDictFree(reader->dict);  | 
2201  | 365k  |     xmlFree(reader);  | 
2202  | 365k  | }  | 
2203  |  |  | 
2204  |  | /************************************************************************  | 
2205  |  |  *                  *  | 
2206  |  |  *      Methods for XmlTextReader     *  | 
2207  |  |  *                  *  | 
2208  |  |  ************************************************************************/  | 
2209  |  | /**  | 
2210  |  |  * xmlTextReaderClose:  | 
2211  |  |  * @reader:  the xmlTextReaderPtr used  | 
2212  |  |  *  | 
2213  |  |  * This method releases any resources allocated by the current instance  | 
2214  |  |  * changes the state to Closed and close any underlying input.  | 
2215  |  |  *  | 
2216  |  |  * Returns 0 or -1 in case of error  | 
2217  |  |  */  | 
2218  |  | int  | 
2219  | 365k  | xmlTextReaderClose(xmlTextReaderPtr reader) { | 
2220  | 365k  |     if (reader == NULL)  | 
2221  | 0  |   return(-1);  | 
2222  | 365k  |     reader->node = NULL;  | 
2223  | 365k  |     reader->curnode = NULL;  | 
2224  | 365k  |     reader->mode = XML_TEXTREADER_MODE_CLOSED;  | 
2225  | 365k  |     if (reader->faketext != NULL) { | 
2226  | 15.8k  |         xmlFreeNode(reader->faketext);  | 
2227  | 15.8k  |         reader->faketext = NULL;  | 
2228  | 15.8k  |     }  | 
2229  | 365k  |     if (reader->ctxt != NULL) { | 
2230  | 365k  | #ifdef LIBXML_VALID_ENABLED  | 
2231  | 365k  |   if ((reader->ctxt->vctxt.vstateTab != NULL) &&  | 
2232  | 365k  |       (reader->ctxt->vctxt.vstateMax > 0)){ | 
2233  | 26.3k  | #ifdef LIBXML_REGEXP_ENABLED  | 
2234  | 96.4k  |             while (reader->ctxt->vctxt.vstateNr > 0)  | 
2235  | 70.1k  |                 xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL);  | 
2236  | 26.3k  | #endif /* LIBXML_REGEXP_ENABLED */  | 
2237  | 26.3k  |       xmlFree(reader->ctxt->vctxt.vstateTab);  | 
2238  | 26.3k  |       reader->ctxt->vctxt.vstateTab = NULL;  | 
2239  | 26.3k  |       reader->ctxt->vctxt.vstateMax = 0;  | 
2240  | 26.3k  |   }  | 
2241  | 365k  | #endif /* LIBXML_VALID_ENABLED */  | 
2242  | 365k  |   xmlStopParser(reader->ctxt);  | 
2243  | 365k  |   if (reader->ctxt->myDoc != NULL) { | 
2244  | 331k  |       if (reader->preserve == 0)  | 
2245  | 331k  |     xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);  | 
2246  | 331k  |       reader->ctxt->myDoc = NULL;  | 
2247  | 331k  |   }  | 
2248  | 365k  |     }  | 
2249  | 365k  |     if ((reader->input != NULL)  && (reader->allocs & XML_TEXTREADER_INPUT)) { | 
2250  | 365k  |   xmlFreeParserInputBuffer(reader->input);  | 
2251  | 365k  |   reader->allocs -= XML_TEXTREADER_INPUT;  | 
2252  | 365k  |     }  | 
2253  | 365k  |     return(0);  | 
2254  | 365k  | }  | 
2255  |  |  | 
2256  |  | /**  | 
2257  |  |  * xmlTextReaderGetAttributeNo:  | 
2258  |  |  * @reader:  the xmlTextReaderPtr used  | 
2259  |  |  * @no: the zero-based index of the attribute relative to the containing element  | 
2260  |  |  *  | 
2261  |  |  * Provides the value of the attribute with the specified index relative  | 
2262  |  |  * to the containing element.  | 
2263  |  |  *  | 
2264  |  |  * Returns a string containing the value of the specified attribute, or NULL  | 
2265  |  |  *    in case of error. The string must be deallocated by the caller.  | 
2266  |  |  */  | 
2267  |  | xmlChar *  | 
2268  | 0  | xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader, int no) { | 
2269  | 0  |     xmlChar *ret;  | 
2270  | 0  |     int i;  | 
2271  | 0  |     xmlAttrPtr cur;  | 
2272  | 0  |     xmlNsPtr ns;  | 
2273  |  | 
  | 
2274  | 0  |     if (reader == NULL)  | 
2275  | 0  |   return(NULL);  | 
2276  | 0  |     if (reader->node == NULL)  | 
2277  | 0  |   return(NULL);  | 
2278  | 0  |     if (reader->curnode != NULL)  | 
2279  | 0  |   return(NULL);  | 
2280  |  |     /* TODO: handle the xmlDecl */  | 
2281  | 0  |     if (reader->node->type != XML_ELEMENT_NODE)  | 
2282  | 0  |   return(NULL);  | 
2283  |  |  | 
2284  | 0  |     ns = reader->node->nsDef;  | 
2285  | 0  |     for (i = 0;(i < no) && (ns != NULL);i++) { | 
2286  | 0  |   ns = ns->next;  | 
2287  | 0  |     }  | 
2288  | 0  |     if (ns != NULL)  | 
2289  | 0  |   return(xmlStrdup(ns->href));  | 
2290  |  |  | 
2291  | 0  |     cur = reader->node->properties;  | 
2292  | 0  |     if (cur == NULL)  | 
2293  | 0  |   return(NULL);  | 
2294  | 0  |     for (;i < no;i++) { | 
2295  | 0  |   cur = cur->next;  | 
2296  | 0  |   if (cur == NULL)  | 
2297  | 0  |       return(NULL);  | 
2298  | 0  |     }  | 
2299  |  |     /* TODO walk the DTD if present */  | 
2300  |  |  | 
2301  | 0  |     ret = xmlNodeListGetString(reader->node->doc, cur->children, 1);  | 
2302  | 0  |     if (ret == NULL) return(xmlStrdup((xmlChar *)""));  | 
2303  | 0  |     return(ret);  | 
2304  | 0  | }  | 
2305  |  |  | 
2306  |  | /**  | 
2307  |  |  * xmlTextReaderGetAttribute:  | 
2308  |  |  * @reader:  the xmlTextReaderPtr used  | 
2309  |  |  * @name: the qualified name of the attribute.  | 
2310  |  |  *  | 
2311  |  |  * Provides the value of the attribute with the specified qualified name.  | 
2312  |  |  *  | 
2313  |  |  * Returns a string containing the value of the specified attribute, or NULL  | 
2314  |  |  *    in case of error. The string must be deallocated by the caller.  | 
2315  |  |  */  | 
2316  |  | xmlChar *  | 
2317  | 0  | xmlTextReaderGetAttribute(xmlTextReaderPtr reader, const xmlChar *name) { | 
2318  | 0  |     xmlChar *prefix = NULL;  | 
2319  | 0  |     xmlChar *localname;  | 
2320  | 0  |     xmlNsPtr ns;  | 
2321  | 0  |     xmlChar *ret = NULL;  | 
2322  |  | 
  | 
2323  | 0  |     if ((reader == NULL) || (name == NULL))  | 
2324  | 0  |   return(NULL);  | 
2325  | 0  |     if (reader->node == NULL)  | 
2326  | 0  |   return(NULL);  | 
2327  | 0  |     if (reader->curnode != NULL)  | 
2328  | 0  |   return(NULL);  | 
2329  |  |  | 
2330  |  |     /* TODO: handle the xmlDecl */  | 
2331  | 0  |     if (reader->node->type != XML_ELEMENT_NODE)  | 
2332  | 0  |   return(NULL);  | 
2333  |  |  | 
2334  | 0  |     localname = xmlSplitQName2(name, &prefix);  | 
2335  | 0  |     if (localname == NULL) { | 
2336  |  |     /*  | 
2337  |  |      * Namespace default decl  | 
2338  |  |      */  | 
2339  | 0  |     if (xmlStrEqual(name, BAD_CAST "xmlns")) { | 
2340  | 0  |       ns = reader->node->nsDef;  | 
2341  | 0  |       while (ns != NULL) { | 
2342  | 0  |         if (ns->prefix == NULL) { | 
2343  | 0  |           return(xmlStrdup(ns->href));  | 
2344  | 0  |         }  | 
2345  | 0  |         ns = ns->next;  | 
2346  | 0  |       }  | 
2347  | 0  |       return NULL;  | 
2348  | 0  |     }  | 
2349  | 0  |     return(xmlGetNoNsProp(reader->node, name));  | 
2350  | 0  |   }  | 
2351  |  |  | 
2352  |  |     /*  | 
2353  |  |      * Namespace default decl  | 
2354  |  |      */  | 
2355  | 0  |     if (xmlStrEqual(prefix, BAD_CAST "xmlns")) { | 
2356  | 0  |     ns = reader->node->nsDef;  | 
2357  | 0  |     while (ns != NULL) { | 
2358  | 0  |       if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) { | 
2359  | 0  |         ret = xmlStrdup(ns->href);  | 
2360  | 0  |         break;  | 
2361  | 0  |       }  | 
2362  | 0  |       ns = ns->next;  | 
2363  | 0  |     }  | 
2364  | 0  |     } else { | 
2365  | 0  |     ns = xmlSearchNs(reader->node->doc, reader->node, prefix);  | 
2366  | 0  |     if (ns != NULL)  | 
2367  | 0  |       ret = xmlGetNsProp(reader->node, localname, ns->href);  | 
2368  | 0  |   }  | 
2369  |  | 
  | 
2370  | 0  |     xmlFree(localname);  | 
2371  | 0  |     if (prefix != NULL)  | 
2372  | 0  |         xmlFree(prefix);  | 
2373  | 0  |     return(ret);  | 
2374  | 0  | }  | 
2375  |  |  | 
2376  |  |  | 
2377  |  | /**  | 
2378  |  |  * xmlTextReaderGetAttributeNs:  | 
2379  |  |  * @reader:  the xmlTextReaderPtr used  | 
2380  |  |  * @localName: the local name of the attribute.  | 
2381  |  |  * @namespaceURI: the namespace URI of the attribute.  | 
2382  |  |  *  | 
2383  |  |  * Provides the value of the specified attribute  | 
2384  |  |  *  | 
2385  |  |  * Returns a string containing the value of the specified attribute, or NULL  | 
2386  |  |  *    in case of error. The string must be deallocated by the caller.  | 
2387  |  |  */  | 
2388  |  | xmlChar *  | 
2389  |  | xmlTextReaderGetAttributeNs(xmlTextReaderPtr reader, const xmlChar *localName,  | 
2390  | 0  |           const xmlChar *namespaceURI) { | 
2391  | 0  |     xmlChar *prefix = NULL;  | 
2392  | 0  |     xmlNsPtr ns;  | 
2393  |  | 
  | 
2394  | 0  |     if ((reader == NULL) || (localName == NULL))  | 
2395  | 0  |   return(NULL);  | 
2396  | 0  |     if (reader->node == NULL)  | 
2397  | 0  |   return(NULL);  | 
2398  | 0  |     if (reader->curnode != NULL)  | 
2399  | 0  |   return(NULL);  | 
2400  |  |  | 
2401  |  |     /* TODO: handle the xmlDecl */  | 
2402  | 0  |     if (reader->node->type != XML_ELEMENT_NODE)  | 
2403  | 0  |   return(NULL);  | 
2404  |  |  | 
2405  | 0  |     if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) { | 
2406  | 0  |     if (! xmlStrEqual(localName, BAD_CAST "xmlns")) { | 
2407  | 0  |       prefix = BAD_CAST localName;  | 
2408  | 0  |     }  | 
2409  | 0  |     ns = reader->node->nsDef;  | 
2410  | 0  |     while (ns != NULL) { | 
2411  | 0  |       if ((prefix == NULL && ns->prefix == NULL) ||  | 
2412  | 0  |         ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) { | 
2413  | 0  |         return xmlStrdup(ns->href);  | 
2414  | 0  |       }  | 
2415  | 0  |       ns = ns->next;  | 
2416  | 0  |     }  | 
2417  | 0  |     return NULL;  | 
2418  | 0  |     }  | 
2419  |  |  | 
2420  | 0  |     return(xmlGetNsProp(reader->node, localName, namespaceURI));  | 
2421  | 0  | }  | 
2422  |  |  | 
2423  |  | /**  | 
2424  |  |  * xmlTextReaderGetRemainder:  | 
2425  |  |  * @reader:  the xmlTextReaderPtr used  | 
2426  |  |  *  | 
2427  |  |  * Method to get the remainder of the buffered XML. this method stops the  | 
2428  |  |  * parser, set its state to End Of File and return the input stream with  | 
2429  |  |  * what is left that the parser did not use.  | 
2430  |  |  *  | 
2431  |  |  * The implementation is not good, the parser certainly progressed past  | 
2432  |  |  * what's left in reader->input, and there is an allocation problem. Best  | 
2433  |  |  * would be to rewrite it differently.  | 
2434  |  |  *  | 
2435  |  |  * Returns the xmlParserInputBufferPtr attached to the XML or NULL  | 
2436  |  |  *    in case of error.  | 
2437  |  |  */  | 
2438  |  | xmlParserInputBufferPtr  | 
2439  | 0  | xmlTextReaderGetRemainder(xmlTextReaderPtr reader) { | 
2440  | 0  |     xmlParserInputBufferPtr ret = NULL;  | 
2441  |  | 
  | 
2442  | 0  |     if (reader == NULL)  | 
2443  | 0  |   return(NULL);  | 
2444  | 0  |     if (reader->node == NULL)  | 
2445  | 0  |   return(NULL);  | 
2446  |  |  | 
2447  | 0  |     reader->node = NULL;  | 
2448  | 0  |     reader->curnode = NULL;  | 
2449  | 0  |     reader->mode = XML_TEXTREADER_MODE_EOF;  | 
2450  | 0  |     if (reader->ctxt != NULL) { | 
2451  | 0  |   xmlStopParser(reader->ctxt);  | 
2452  | 0  |   if (reader->ctxt->myDoc != NULL) { | 
2453  | 0  |       if (reader->preserve == 0)  | 
2454  | 0  |     xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);  | 
2455  | 0  |       reader->ctxt->myDoc = NULL;  | 
2456  | 0  |   }  | 
2457  | 0  |     }  | 
2458  | 0  |     if (reader->allocs & XML_TEXTREADER_INPUT) { | 
2459  | 0  |   ret = reader->input;  | 
2460  | 0  |   reader->input = NULL;  | 
2461  | 0  |   reader->allocs -= XML_TEXTREADER_INPUT;  | 
2462  | 0  |     } else { | 
2463  |  |   /*  | 
2464  |  |    * Hum, one may need to duplicate the data structure because  | 
2465  |  |    * without reference counting the input may be freed twice:  | 
2466  |  |    *   - by the layer which allocated it.  | 
2467  |  |    *   - by the layer to which would have been returned to.  | 
2468  |  |    */  | 
2469  | 0  |   TODO  | 
2470  | 0  |   return(NULL);  | 
2471  | 0  |     }  | 
2472  | 0  |     return(ret);  | 
2473  | 0  | }  | 
2474  |  |  | 
2475  |  | /**  | 
2476  |  |  * xmlTextReaderLookupNamespace:  | 
2477  |  |  * @reader:  the xmlTextReaderPtr used  | 
2478  |  |  * @prefix: the prefix whose namespace URI is to be resolved. To return  | 
2479  |  |  *          the default namespace, specify NULL  | 
2480  |  |  *  | 
2481  |  |  * Resolves a namespace prefix in the scope of the current element.  | 
2482  |  |  *  | 
2483  |  |  * Returns a string containing the namespace URI to which the prefix maps  | 
2484  |  |  *    or NULL in case of error. The string must be deallocated by the caller.  | 
2485  |  |  */  | 
2486  |  | xmlChar *  | 
2487  | 0  | xmlTextReaderLookupNamespace(xmlTextReaderPtr reader, const xmlChar *prefix) { | 
2488  | 0  |     xmlNsPtr ns;  | 
2489  |  | 
  | 
2490  | 0  |     if (reader == NULL)  | 
2491  | 0  |   return(NULL);  | 
2492  | 0  |     if (reader->node == NULL)  | 
2493  | 0  |   return(NULL);  | 
2494  |  |  | 
2495  | 0  |     ns = xmlSearchNs(reader->node->doc, reader->node, prefix);  | 
2496  | 0  |     if (ns == NULL)  | 
2497  | 0  |   return(NULL);  | 
2498  | 0  |     return(xmlStrdup(ns->href));  | 
2499  | 0  | }  | 
2500  |  |  | 
2501  |  | /**  | 
2502  |  |  * xmlTextReaderMoveToAttributeNo:  | 
2503  |  |  * @reader:  the xmlTextReaderPtr used  | 
2504  |  |  * @no: the zero-based index of the attribute relative to the containing  | 
2505  |  |  *      element.  | 
2506  |  |  *  | 
2507  |  |  * Moves the position of the current instance to the attribute with  | 
2508  |  |  * the specified index relative to the containing element.  | 
2509  |  |  *  | 
2510  |  |  * Returns 1 in case of success, -1 in case of error, 0 if not found  | 
2511  |  |  */  | 
2512  |  | int  | 
2513  | 6.14M  | xmlTextReaderMoveToAttributeNo(xmlTextReaderPtr reader, int no) { | 
2514  | 6.14M  |     int i;  | 
2515  | 6.14M  |     xmlAttrPtr cur;  | 
2516  | 6.14M  |     xmlNsPtr ns;  | 
2517  |  |  | 
2518  | 6.14M  |     if (reader == NULL)  | 
2519  | 0  |   return(-1);  | 
2520  | 6.14M  |     if (reader->node == NULL)  | 
2521  | 0  |   return(-1);  | 
2522  |  |     /* TODO: handle the xmlDecl */  | 
2523  | 6.14M  |     if (reader->node->type != XML_ELEMENT_NODE)  | 
2524  | 0  |   return(-1);  | 
2525  |  |  | 
2526  | 6.14M  |     reader->curnode = NULL;  | 
2527  |  |  | 
2528  | 6.14M  |     ns = reader->node->nsDef;  | 
2529  | 6.32M  |     for (i = 0;(i < no) && (ns != NULL);i++) { | 
2530  | 181k  |   ns = ns->next;  | 
2531  | 181k  |     }  | 
2532  | 6.14M  |     if (ns != NULL) { | 
2533  | 700k  |   reader->curnode = (xmlNodePtr) ns;  | 
2534  | 700k  |   return(1);  | 
2535  | 700k  |     }  | 
2536  |  |  | 
2537  | 5.44M  |     cur = reader->node->properties;  | 
2538  | 5.44M  |     if (cur == NULL)  | 
2539  | 0  |   return(0);  | 
2540  | 7.61M  |     for (;i < no;i++) { | 
2541  | 2.16M  |   cur = cur->next;  | 
2542  | 2.16M  |   if (cur == NULL)  | 
2543  | 0  |       return(0);  | 
2544  | 2.16M  |     }  | 
2545  |  |     /* TODO walk the DTD if present */  | 
2546  |  |  | 
2547  | 5.44M  |     reader->curnode = (xmlNodePtr) cur;  | 
2548  | 5.44M  |     return(1);  | 
2549  | 5.44M  | }  | 
2550  |  |  | 
2551  |  | /**  | 
2552  |  |  * xmlTextReaderMoveToAttribute:  | 
2553  |  |  * @reader:  the xmlTextReaderPtr used  | 
2554  |  |  * @name: the qualified name of the attribute.  | 
2555  |  |  *  | 
2556  |  |  * Moves the position of the current instance to the attribute with  | 
2557  |  |  * the specified qualified name.  | 
2558  |  |  *  | 
2559  |  |  * Returns 1 in case of success, -1 in case of error, 0 if not found  | 
2560  |  |  */  | 
2561  |  | int  | 
2562  | 0  | xmlTextReaderMoveToAttribute(xmlTextReaderPtr reader, const xmlChar *name) { | 
2563  | 0  |     xmlChar *prefix = NULL;  | 
2564  | 0  |     xmlChar *localname;  | 
2565  | 0  |     xmlNsPtr ns;  | 
2566  | 0  |     xmlAttrPtr prop;  | 
2567  |  | 
  | 
2568  | 0  |     if ((reader == NULL) || (name == NULL))  | 
2569  | 0  |   return(-1);  | 
2570  | 0  |     if (reader->node == NULL)  | 
2571  | 0  |   return(-1);  | 
2572  |  |  | 
2573  |  |     /* TODO: handle the xmlDecl */  | 
2574  | 0  |     if (reader->node->type != XML_ELEMENT_NODE)  | 
2575  | 0  |   return(0);  | 
2576  |  |  | 
2577  | 0  |     localname = xmlSplitQName2(name, &prefix);  | 
2578  | 0  |     if (localname == NULL) { | 
2579  |  |   /*  | 
2580  |  |    * Namespace default decl  | 
2581  |  |    */  | 
2582  | 0  |   if (xmlStrEqual(name, BAD_CAST "xmlns")) { | 
2583  | 0  |       ns = reader->node->nsDef;  | 
2584  | 0  |       while (ns != NULL) { | 
2585  | 0  |     if (ns->prefix == NULL) { | 
2586  | 0  |         reader->curnode = (xmlNodePtr) ns;  | 
2587  | 0  |         return(1);  | 
2588  | 0  |     }  | 
2589  | 0  |     ns = ns->next;  | 
2590  | 0  |       }  | 
2591  | 0  |       return(0);  | 
2592  | 0  |   }  | 
2593  |  |  | 
2594  | 0  |   prop = reader->node->properties;  | 
2595  | 0  |   while (prop != NULL) { | 
2596  |  |       /*  | 
2597  |  |        * One need to have  | 
2598  |  |        *   - same attribute names  | 
2599  |  |        *   - and the attribute carrying that namespace  | 
2600  |  |        */  | 
2601  | 0  |       if ((xmlStrEqual(prop->name, name)) &&  | 
2602  | 0  |     ((prop->ns == NULL) || (prop->ns->prefix == NULL))) { | 
2603  | 0  |     reader->curnode = (xmlNodePtr) prop;  | 
2604  | 0  |     return(1);  | 
2605  | 0  |       }  | 
2606  | 0  |       prop = prop->next;  | 
2607  | 0  |   }  | 
2608  | 0  |   return(0);  | 
2609  | 0  |     }  | 
2610  |  |  | 
2611  |  |     /*  | 
2612  |  |      * Namespace default decl  | 
2613  |  |      */  | 
2614  | 0  |     if (xmlStrEqual(prefix, BAD_CAST "xmlns")) { | 
2615  | 0  |   ns = reader->node->nsDef;  | 
2616  | 0  |   while (ns != NULL) { | 
2617  | 0  |       if ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localname))) { | 
2618  | 0  |     reader->curnode = (xmlNodePtr) ns;  | 
2619  | 0  |     goto found;  | 
2620  | 0  |       }  | 
2621  | 0  |       ns = ns->next;  | 
2622  | 0  |   }  | 
2623  | 0  |   goto not_found;  | 
2624  | 0  |     }  | 
2625  | 0  |     prop = reader->node->properties;  | 
2626  | 0  |     while (prop != NULL) { | 
2627  |  |   /*  | 
2628  |  |    * One need to have  | 
2629  |  |    *   - same attribute names  | 
2630  |  |    *   - and the attribute carrying that namespace  | 
2631  |  |    */  | 
2632  | 0  |   if ((xmlStrEqual(prop->name, localname)) &&  | 
2633  | 0  |       (prop->ns != NULL) && (xmlStrEqual(prop->ns->prefix, prefix))) { | 
2634  | 0  |       reader->curnode = (xmlNodePtr) prop;  | 
2635  | 0  |       goto found;  | 
2636  | 0  |   }  | 
2637  | 0  |   prop = prop->next;  | 
2638  | 0  |     }  | 
2639  | 0  | not_found:  | 
2640  | 0  |     if (localname != NULL)  | 
2641  | 0  |         xmlFree(localname);  | 
2642  | 0  |     if (prefix != NULL)  | 
2643  | 0  |         xmlFree(prefix);  | 
2644  | 0  |     return(0);  | 
2645  |  |  | 
2646  | 0  | found:  | 
2647  | 0  |     if (localname != NULL)  | 
2648  | 0  |         xmlFree(localname);  | 
2649  | 0  |     if (prefix != NULL)  | 
2650  | 0  |         xmlFree(prefix);  | 
2651  | 0  |     return(1);  | 
2652  | 0  | }  | 
2653  |  |  | 
2654  |  | /**  | 
2655  |  |  * xmlTextReaderMoveToAttributeNs:  | 
2656  |  |  * @reader:  the xmlTextReaderPtr used  | 
2657  |  |  * @localName:  the local name of the attribute.  | 
2658  |  |  * @namespaceURI:  the namespace URI of the attribute.  | 
2659  |  |  *  | 
2660  |  |  * Moves the position of the current instance to the attribute with the  | 
2661  |  |  * specified local name and namespace URI.  | 
2662  |  |  *  | 
2663  |  |  * Returns 1 in case of success, -1 in case of error, 0 if not found  | 
2664  |  |  */  | 
2665  |  | int  | 
2666  |  | xmlTextReaderMoveToAttributeNs(xmlTextReaderPtr reader,  | 
2667  | 0  |   const xmlChar *localName, const xmlChar *namespaceURI) { | 
2668  | 0  |     xmlAttrPtr prop;  | 
2669  | 0  |     xmlNodePtr node;  | 
2670  | 0  |     xmlNsPtr ns;  | 
2671  | 0  |     xmlChar *prefix = NULL;  | 
2672  |  | 
  | 
2673  | 0  |     if ((reader == NULL) || (localName == NULL) || (namespaceURI == NULL))  | 
2674  | 0  |   return(-1);  | 
2675  | 0  |     if (reader->node == NULL)  | 
2676  | 0  |   return(-1);  | 
2677  | 0  |     if (reader->node->type != XML_ELEMENT_NODE)  | 
2678  | 0  |   return(0);  | 
2679  | 0  |     node = reader->node;  | 
2680  |  | 
  | 
2681  | 0  |     if (xmlStrEqual(namespaceURI, BAD_CAST "http://www.w3.org/2000/xmlns/")) { | 
2682  | 0  |     if (! xmlStrEqual(localName, BAD_CAST "xmlns")) { | 
2683  | 0  |       prefix = BAD_CAST localName;  | 
2684  | 0  |     }  | 
2685  | 0  |     ns = reader->node->nsDef;  | 
2686  | 0  |     while (ns != NULL) { | 
2687  | 0  |       if ((prefix == NULL && ns->prefix == NULL) ||  | 
2688  | 0  |         ((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) { | 
2689  | 0  |         reader->curnode = (xmlNodePtr) ns;  | 
2690  | 0  |         return(1);  | 
2691  | 0  |       }  | 
2692  | 0  |       ns = ns->next;  | 
2693  | 0  |     }  | 
2694  | 0  |     return(0);  | 
2695  | 0  |     }  | 
2696  |  |  | 
2697  | 0  |     prop = node->properties;  | 
2698  | 0  |     while (prop != NULL) { | 
2699  |  |   /*  | 
2700  |  |    * One need to have  | 
2701  |  |    *   - same attribute names  | 
2702  |  |    *   - and the attribute carrying that namespace  | 
2703  |  |    */  | 
2704  | 0  |         if (xmlStrEqual(prop->name, localName) &&  | 
2705  | 0  |       ((prop->ns != NULL) &&  | 
2706  | 0  |        (xmlStrEqual(prop->ns->href, namespaceURI)))) { | 
2707  | 0  |       reader->curnode = (xmlNodePtr) prop;  | 
2708  | 0  |       return(1);  | 
2709  | 0  |         }  | 
2710  | 0  |   prop = prop->next;  | 
2711  | 0  |     }  | 
2712  | 0  |     return(0);  | 
2713  | 0  | }  | 
2714  |  |  | 
2715  |  | /**  | 
2716  |  |  * xmlTextReaderMoveToFirstAttribute:  | 
2717  |  |  * @reader:  the xmlTextReaderPtr used  | 
2718  |  |  *  | 
2719  |  |  * Moves the position of the current instance to the first attribute  | 
2720  |  |  * associated with the current node.  | 
2721  |  |  *  | 
2722  |  |  * Returns 1 in case of success, -1 in case of error, 0 if not found  | 
2723  |  |  */  | 
2724  |  | int  | 
2725  | 0  | xmlTextReaderMoveToFirstAttribute(xmlTextReaderPtr reader) { | 
2726  | 0  |     if (reader == NULL)  | 
2727  | 0  |   return(-1);  | 
2728  | 0  |     if (reader->node == NULL)  | 
2729  | 0  |   return(-1);  | 
2730  | 0  |     if (reader->node->type != XML_ELEMENT_NODE)  | 
2731  | 0  |   return(0);  | 
2732  |  |  | 
2733  | 0  |     if (reader->node->nsDef != NULL) { | 
2734  | 0  |   reader->curnode = (xmlNodePtr) reader->node->nsDef;  | 
2735  | 0  |   return(1);  | 
2736  | 0  |     }  | 
2737  | 0  |     if (reader->node->properties != NULL) { | 
2738  | 0  |   reader->curnode = (xmlNodePtr) reader->node->properties;  | 
2739  | 0  |   return(1);  | 
2740  | 0  |     }  | 
2741  | 0  |     return(0);  | 
2742  | 0  | }  | 
2743  |  |  | 
2744  |  | /**  | 
2745  |  |  * xmlTextReaderMoveToNextAttribute:  | 
2746  |  |  * @reader:  the xmlTextReaderPtr used  | 
2747  |  |  *  | 
2748  |  |  * Moves the position of the current instance to the next attribute  | 
2749  |  |  * associated with the current node.  | 
2750  |  |  *  | 
2751  |  |  * Returns 1 in case of success, -1 in case of error, 0 if not found  | 
2752  |  |  */  | 
2753  |  | int  | 
2754  | 0  | xmlTextReaderMoveToNextAttribute(xmlTextReaderPtr reader) { | 
2755  | 0  |     if (reader == NULL)  | 
2756  | 0  |   return(-1);  | 
2757  | 0  |     if (reader->node == NULL)  | 
2758  | 0  |   return(-1);  | 
2759  | 0  |     if (reader->node->type != XML_ELEMENT_NODE)  | 
2760  | 0  |   return(0);  | 
2761  | 0  |     if (reader->curnode == NULL)  | 
2762  | 0  |   return(xmlTextReaderMoveToFirstAttribute(reader));  | 
2763  |  |  | 
2764  | 0  |     if (reader->curnode->type == XML_NAMESPACE_DECL) { | 
2765  | 0  |   xmlNsPtr ns = (xmlNsPtr) reader->curnode;  | 
2766  | 0  |   if (ns->next != NULL) { | 
2767  | 0  |       reader->curnode = (xmlNodePtr) ns->next;  | 
2768  | 0  |       return(1);  | 
2769  | 0  |   }  | 
2770  | 0  |   if (reader->node->properties != NULL) { | 
2771  | 0  |       reader->curnode = (xmlNodePtr) reader->node->properties;  | 
2772  | 0  |       return(1);  | 
2773  | 0  |   }  | 
2774  | 0  |   return(0);  | 
2775  | 0  |     } else if ((reader->curnode->type == XML_ATTRIBUTE_NODE) &&  | 
2776  | 0  |          (reader->curnode->next != NULL)) { | 
2777  | 0  |   reader->curnode = reader->curnode->next;  | 
2778  | 0  |   return(1);  | 
2779  | 0  |     }  | 
2780  | 0  |     return(0);  | 
2781  | 0  | }  | 
2782  |  |  | 
2783  |  | /**  | 
2784  |  |  * xmlTextReaderMoveToElement:  | 
2785  |  |  * @reader:  the xmlTextReaderPtr used  | 
2786  |  |  *  | 
2787  |  |  * Moves the position of the current instance to the node that  | 
2788  |  |  * contains the current Attribute  node.  | 
2789  |  |  *  | 
2790  |  |  * Returns 1 in case of success, -1 in case of error, 0 if not moved  | 
2791  |  |  */  | 
2792  |  | int  | 
2793  | 0  | xmlTextReaderMoveToElement(xmlTextReaderPtr reader) { | 
2794  | 0  |     if (reader == NULL)  | 
2795  | 0  |   return(-1);  | 
2796  | 0  |     if (reader->node == NULL)  | 
2797  | 0  |   return(-1);  | 
2798  | 0  |     if (reader->node->type != XML_ELEMENT_NODE)  | 
2799  | 0  |   return(0);  | 
2800  | 0  |     if (reader->curnode != NULL) { | 
2801  | 0  |   reader->curnode = NULL;  | 
2802  | 0  |   return(1);  | 
2803  | 0  |     }  | 
2804  | 0  |     return(0);  | 
2805  | 0  | }  | 
2806  |  |  | 
2807  |  | /**  | 
2808  |  |  * xmlTextReaderReadAttributeValue:  | 
2809  |  |  * @reader:  the xmlTextReaderPtr used  | 
2810  |  |  *  | 
2811  |  |  * Parses an attribute value into one or more Text and EntityReference nodes.  | 
2812  |  |  *  | 
2813  |  |  * Returns 1 in case of success, 0 if the reader was not positioned on an  | 
2814  |  |  *         attribute node or all the attribute values have been read, or -1  | 
2815  |  |  *         in case of error.  | 
2816  |  |  */  | 
2817  |  | int  | 
2818  | 12.5M  | xmlTextReaderReadAttributeValue(xmlTextReaderPtr reader) { | 
2819  | 12.5M  |     if (reader == NULL)  | 
2820  | 0  |   return(-1);  | 
2821  | 12.5M  |     if (reader->node == NULL)  | 
2822  | 0  |   return(-1);  | 
2823  | 12.5M  |     if (reader->curnode == NULL)  | 
2824  | 0  |   return(0);  | 
2825  | 12.5M  |     if (reader->curnode->type == XML_ATTRIBUTE_NODE) { | 
2826  | 5.44M  |   if (reader->curnode->children == NULL)  | 
2827  | 696  |       return(0);  | 
2828  | 5.44M  |   reader->curnode = reader->curnode->children;  | 
2829  | 7.11M  |     } else if (reader->curnode->type == XML_NAMESPACE_DECL) { | 
2830  | 700k  |   xmlNsPtr ns = (xmlNsPtr) reader->curnode;  | 
2831  |  |  | 
2832  | 700k  |   if (reader->faketext == NULL) { | 
2833  | 15.8k  |       reader->faketext = xmlNewDocText(reader->node->doc,  | 
2834  | 15.8k  |                                  ns->href);  | 
2835  | 684k  |   } else { | 
2836  | 684k  |             if ((reader->faketext->content != NULL) &&  | 
2837  | 684k  |           (reader->faketext->content !=  | 
2838  | 535k  |      (xmlChar *) &(reader->faketext->properties)))  | 
2839  | 535k  |     xmlFree(reader->faketext->content);  | 
2840  | 684k  |       reader->faketext->content = xmlStrdup(ns->href);  | 
2841  | 684k  |   }  | 
2842  | 700k  |   reader->curnode = reader->faketext;  | 
2843  | 6.40M  |     } else { | 
2844  | 6.40M  |   if (reader->curnode->next == NULL)  | 
2845  | 6.14M  |       return(0);  | 
2846  | 264k  |   reader->curnode = reader->curnode->next;  | 
2847  | 264k  |     }  | 
2848  | 6.40M  |     return(1);  | 
2849  | 12.5M  | }  | 
2850  |  |  | 
2851  |  | /**  | 
2852  |  |  * xmlTextReaderConstEncoding:  | 
2853  |  |  * @reader:  the xmlTextReaderPtr used  | 
2854  |  |  *  | 
2855  |  |  * Determine the encoding of the document being read.  | 
2856  |  |  *  | 
2857  |  |  * Returns a string containing the encoding of the document or NULL in  | 
2858  |  |  * case of error.  The string is deallocated with the reader.  | 
2859  |  |  */  | 
2860  |  | const xmlChar *  | 
2861  | 0  | xmlTextReaderConstEncoding(xmlTextReaderPtr reader) { | 
2862  | 0  |     xmlDocPtr doc = NULL;  | 
2863  | 0  |     if (reader == NULL)  | 
2864  | 0  |   return(NULL);  | 
2865  | 0  |     if (reader->doc != NULL)  | 
2866  | 0  |         doc = reader->doc;  | 
2867  | 0  |     else if (reader->ctxt != NULL)  | 
2868  | 0  |   doc = reader->ctxt->myDoc;  | 
2869  | 0  |     if (doc == NULL)  | 
2870  | 0  |   return(NULL);  | 
2871  |  |  | 
2872  | 0  |     if (doc->encoding == NULL)  | 
2873  | 0  |   return(NULL);  | 
2874  | 0  |     else  | 
2875  | 0  |       return(CONSTSTR(doc->encoding));  | 
2876  | 0  | }  | 
2877  |  |  | 
2878  |  |  | 
2879  |  | /************************************************************************  | 
2880  |  |  *                  *  | 
2881  |  |  *      Access API to the current node      *  | 
2882  |  |  *                  *  | 
2883  |  |  ************************************************************************/  | 
2884  |  | /**  | 
2885  |  |  * xmlTextReaderAttributeCount:  | 
2886  |  |  * @reader:  the xmlTextReaderPtr used  | 
2887  |  |  *  | 
2888  |  |  * Provides the number of attributes of the current node  | 
2889  |  |  *  | 
2890  |  |  * Returns 0 i no attributes, -1 in case of error or the attribute count  | 
2891  |  |  */  | 
2892  |  | int  | 
2893  | 6.40M  | xmlTextReaderAttributeCount(xmlTextReaderPtr reader) { | 
2894  | 6.40M  |     int ret;  | 
2895  | 6.40M  |     xmlAttrPtr attr;  | 
2896  | 6.40M  |     xmlNsPtr ns;  | 
2897  | 6.40M  |     xmlNodePtr node;  | 
2898  |  |  | 
2899  | 6.40M  |     if (reader == NULL)  | 
2900  | 0  |   return(-1);  | 
2901  | 6.40M  |     if (reader->node == NULL)  | 
2902  | 0  |   return(0);  | 
2903  |  |  | 
2904  | 6.40M  |     if (reader->curnode != NULL)  | 
2905  | 0  |   node = reader->curnode;  | 
2906  | 6.40M  |     else  | 
2907  | 6.40M  |   node = reader->node;  | 
2908  |  |  | 
2909  | 6.40M  |     if (node->type != XML_ELEMENT_NODE)  | 
2910  | 0  |   return(0);  | 
2911  | 6.40M  |     if ((reader->state == XML_TEXTREADER_END) ||  | 
2912  | 6.40M  |   (reader->state == XML_TEXTREADER_BACKTRACK))  | 
2913  | 0  |   return(0);  | 
2914  | 6.40M  |     ret = 0;  | 
2915  | 6.40M  |     attr = node->properties;  | 
2916  | 11.8M  |     while (attr != NULL) { | 
2917  | 5.44M  |   ret++;  | 
2918  | 5.44M  |   attr = attr->next;  | 
2919  | 5.44M  |     }  | 
2920  | 6.40M  |     ns = node->nsDef;  | 
2921  | 7.10M  |     while (ns != NULL) { | 
2922  | 700k  |   ret++;  | 
2923  | 700k  |   ns = ns->next;  | 
2924  | 700k  |     }  | 
2925  | 6.40M  |     return(ret);  | 
2926  | 6.40M  | }  | 
2927  |  |  | 
2928  |  | /**  | 
2929  |  |  * xmlTextReaderNodeType:  | 
2930  |  |  * @reader:  the xmlTextReaderPtr used  | 
2931  |  |  *  | 
2932  |  |  * Get the node type of the current node  | 
2933  |  |  * Reference:  | 
2934  |  |  * http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html  | 
2935  |  |  *  | 
2936  |  |  * Returns the xmlReaderTypes of the current node or -1 in case of error  | 
2937  |  |  */  | 
2938  |  | int  | 
2939  | 20.9M  | xmlTextReaderNodeType(xmlTextReaderPtr reader) { | 
2940  | 20.9M  |     xmlNodePtr node;  | 
2941  |  |  | 
2942  | 20.9M  |     if (reader == NULL)  | 
2943  | 0  |   return(-1);  | 
2944  | 20.9M  |     if (reader->node == NULL)  | 
2945  | 0  |   return(XML_READER_TYPE_NONE);  | 
2946  | 20.9M  |     if (reader->curnode != NULL)  | 
2947  | 0  |   node = reader->curnode;  | 
2948  | 20.9M  |     else  | 
2949  | 20.9M  |   node = reader->node;  | 
2950  | 20.9M  |     switch (node->type) { | 
2951  | 11.1M  |         case XML_ELEMENT_NODE:  | 
2952  | 11.1M  |       if ((reader->state == XML_TEXTREADER_END) ||  | 
2953  | 11.1M  |     (reader->state == XML_TEXTREADER_BACKTRACK))  | 
2954  | 4.72M  |     return(XML_READER_TYPE_END_ELEMENT);  | 
2955  | 6.40M  |       return(XML_READER_TYPE_ELEMENT);  | 
2956  | 0  |         case XML_NAMESPACE_DECL:  | 
2957  | 0  |         case XML_ATTRIBUTE_NODE:  | 
2958  | 0  |       return(XML_READER_TYPE_ATTRIBUTE);  | 
2959  | 8.65M  |         case XML_TEXT_NODE:  | 
2960  | 8.65M  |       if (xmlIsBlankNode(reader->node)) { | 
2961  | 3.57M  |     if (xmlNodeGetSpacePreserve(reader->node))  | 
2962  | 3.57M  |         return(XML_READER_TYPE_SIGNIFICANT_WHITESPACE);  | 
2963  | 0  |     else  | 
2964  | 0  |         return(XML_READER_TYPE_WHITESPACE);  | 
2965  | 5.08M  |       } else { | 
2966  | 5.08M  |     return(XML_READER_TYPE_TEXT);  | 
2967  | 5.08M  |       }  | 
2968  | 126k  |         case XML_CDATA_SECTION_NODE:  | 
2969  | 126k  |       return(XML_READER_TYPE_CDATA);  | 
2970  | 310k  |         case XML_ENTITY_REF_NODE:  | 
2971  | 310k  |       return(XML_READER_TYPE_ENTITY_REFERENCE);  | 
2972  | 0  |         case XML_ENTITY_NODE:  | 
2973  | 0  |       return(XML_READER_TYPE_ENTITY);  | 
2974  | 208k  |         case XML_PI_NODE:  | 
2975  | 208k  |       return(XML_READER_TYPE_PROCESSING_INSTRUCTION);  | 
2976  | 502k  |         case XML_COMMENT_NODE:  | 
2977  | 502k  |       return(XML_READER_TYPE_COMMENT);  | 
2978  | 0  |         case XML_DOCUMENT_NODE:  | 
2979  | 0  |         case XML_HTML_DOCUMENT_NODE:  | 
2980  | 0  |       return(XML_READER_TYPE_DOCUMENT);  | 
2981  | 0  |         case XML_DOCUMENT_FRAG_NODE:  | 
2982  | 0  |       return(XML_READER_TYPE_DOCUMENT_FRAGMENT);  | 
2983  | 0  |         case XML_NOTATION_NODE:  | 
2984  | 0  |       return(XML_READER_TYPE_NOTATION);  | 
2985  | 0  |         case XML_DOCUMENT_TYPE_NODE:  | 
2986  | 51.0k  |         case XML_DTD_NODE:  | 
2987  | 51.0k  |       return(XML_READER_TYPE_DOCUMENT_TYPE);  | 
2988  |  |  | 
2989  | 0  |         case XML_ELEMENT_DECL:  | 
2990  | 0  |         case XML_ATTRIBUTE_DECL:  | 
2991  | 0  |         case XML_ENTITY_DECL:  | 
2992  | 0  |         case XML_XINCLUDE_START:  | 
2993  | 0  |         case XML_XINCLUDE_END:  | 
2994  | 0  |       return(XML_READER_TYPE_NONE);  | 
2995  | 20.9M  |     }  | 
2996  | 0  |     return(-1);  | 
2997  | 20.9M  | }  | 
2998  |  |  | 
2999  |  | /**  | 
3000  |  |  * xmlTextReaderIsEmptyElement:  | 
3001  |  |  * @reader:  the xmlTextReaderPtr used  | 
3002  |  |  *  | 
3003  |  |  * Check if the current node is empty  | 
3004  |  |  *  | 
3005  |  |  * Returns 1 if empty, 0 if not and -1 in case of error  | 
3006  |  |  */  | 
3007  |  | int  | 
3008  | 0  | xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader) { | 
3009  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3010  | 0  |   return(-1);  | 
3011  | 0  |     if (reader->node->type != XML_ELEMENT_NODE)  | 
3012  | 0  |   return(0);  | 
3013  | 0  |     if (reader->curnode != NULL)  | 
3014  | 0  |   return(0);  | 
3015  | 0  |     if (reader->node->children != NULL)  | 
3016  | 0  |   return(0);  | 
3017  | 0  |     if (reader->state == XML_TEXTREADER_END)  | 
3018  | 0  |   return(0);  | 
3019  | 0  |     if (reader->doc != NULL)  | 
3020  | 0  |         return(1);  | 
3021  | 0  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
3022  | 0  |     if (reader->in_xinclude > 0)  | 
3023  | 0  |         return(1);  | 
3024  | 0  | #endif  | 
3025  | 0  |     return((reader->node->extra & NODE_IS_EMPTY) != 0);  | 
3026  | 0  | }  | 
3027  |  |  | 
3028  |  | /**  | 
3029  |  |  * xmlTextReaderLocalName:  | 
3030  |  |  * @reader:  the xmlTextReaderPtr used  | 
3031  |  |  *  | 
3032  |  |  * The local name of the node.  | 
3033  |  |  *  | 
3034  |  |  * Returns the local name or NULL if not available,  | 
3035  |  |  *   if non NULL it need to be freed by the caller.  | 
3036  |  |  */  | 
3037  |  | xmlChar *  | 
3038  | 0  | xmlTextReaderLocalName(xmlTextReaderPtr reader) { | 
3039  | 0  |     xmlNodePtr node;  | 
3040  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3041  | 0  |   return(NULL);  | 
3042  | 0  |     if (reader->curnode != NULL)  | 
3043  | 0  |   node = reader->curnode;  | 
3044  | 0  |     else  | 
3045  | 0  |   node = reader->node;  | 
3046  | 0  |     if (node->type == XML_NAMESPACE_DECL) { | 
3047  | 0  |   xmlNsPtr ns = (xmlNsPtr) node;  | 
3048  | 0  |   if (ns->prefix == NULL)  | 
3049  | 0  |       return(xmlStrdup(BAD_CAST "xmlns"));  | 
3050  | 0  |   else  | 
3051  | 0  |       return(xmlStrdup(ns->prefix));  | 
3052  | 0  |     }  | 
3053  | 0  |     if ((node->type != XML_ELEMENT_NODE) &&  | 
3054  | 0  |   (node->type != XML_ATTRIBUTE_NODE))  | 
3055  | 0  |   return(xmlTextReaderName(reader));  | 
3056  | 0  |     return(xmlStrdup(node->name));  | 
3057  | 0  | }  | 
3058  |  |  | 
3059  |  | /**  | 
3060  |  |  * xmlTextReaderConstLocalName:  | 
3061  |  |  * @reader:  the xmlTextReaderPtr used  | 
3062  |  |  *  | 
3063  |  |  * The local name of the node.  | 
3064  |  |  *  | 
3065  |  |  * Returns the local name or NULL if not available, the  | 
3066  |  |  *         string will be deallocated with the reader.  | 
3067  |  |  */  | 
3068  |  | const xmlChar *  | 
3069  | 0  | xmlTextReaderConstLocalName(xmlTextReaderPtr reader) { | 
3070  | 0  |     xmlNodePtr node;  | 
3071  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3072  | 0  |   return(NULL);  | 
3073  | 0  |     if (reader->curnode != NULL)  | 
3074  | 0  |   node = reader->curnode;  | 
3075  | 0  |     else  | 
3076  | 0  |   node = reader->node;  | 
3077  | 0  |     if (node->type == XML_NAMESPACE_DECL) { | 
3078  | 0  |   xmlNsPtr ns = (xmlNsPtr) node;  | 
3079  | 0  |   if (ns->prefix == NULL)  | 
3080  | 0  |       return(CONSTSTR(BAD_CAST "xmlns"));  | 
3081  | 0  |   else  | 
3082  | 0  |       return(ns->prefix);  | 
3083  | 0  |     }  | 
3084  | 0  |     if ((node->type != XML_ELEMENT_NODE) &&  | 
3085  | 0  |   (node->type != XML_ATTRIBUTE_NODE))  | 
3086  | 0  |   return(xmlTextReaderConstName(reader));  | 
3087  | 0  |     return(node->name);  | 
3088  | 0  | }  | 
3089  |  |  | 
3090  |  | /**  | 
3091  |  |  * xmlTextReaderName:  | 
3092  |  |  * @reader:  the xmlTextReaderPtr used  | 
3093  |  |  *  | 
3094  |  |  * The qualified name of the node, equal to Prefix :LocalName.  | 
3095  |  |  *  | 
3096  |  |  * Returns the local name or NULL if not available,  | 
3097  |  |  *   if non NULL it need to be freed by the caller.  | 
3098  |  |  */  | 
3099  |  | xmlChar *  | 
3100  | 0  | xmlTextReaderName(xmlTextReaderPtr reader) { | 
3101  | 0  |     xmlNodePtr node;  | 
3102  | 0  |     xmlChar *ret;  | 
3103  |  | 
  | 
3104  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3105  | 0  |   return(NULL);  | 
3106  | 0  |     if (reader->curnode != NULL)  | 
3107  | 0  |   node = reader->curnode;  | 
3108  | 0  |     else  | 
3109  | 0  |   node = reader->node;  | 
3110  | 0  |     switch (node->type) { | 
3111  | 0  |         case XML_ELEMENT_NODE:  | 
3112  | 0  |         case XML_ATTRIBUTE_NODE:  | 
3113  | 0  |       if ((node->ns == NULL) ||  | 
3114  | 0  |     (node->ns->prefix == NULL))  | 
3115  | 0  |     return(xmlStrdup(node->name));  | 
3116  |  |  | 
3117  | 0  |       ret = xmlStrdup(node->ns->prefix);  | 
3118  | 0  |       ret = xmlStrcat(ret, BAD_CAST ":");  | 
3119  | 0  |       ret = xmlStrcat(ret, node->name);  | 
3120  | 0  |       return(ret);  | 
3121  | 0  |         case XML_TEXT_NODE:  | 
3122  | 0  |       return(xmlStrdup(BAD_CAST "#text"));  | 
3123  | 0  |         case XML_CDATA_SECTION_NODE:  | 
3124  | 0  |       return(xmlStrdup(BAD_CAST "#cdata-section"));  | 
3125  | 0  |         case XML_ENTITY_NODE:  | 
3126  | 0  |         case XML_ENTITY_REF_NODE:  | 
3127  | 0  |       return(xmlStrdup(node->name));  | 
3128  | 0  |         case XML_PI_NODE:  | 
3129  | 0  |       return(xmlStrdup(node->name));  | 
3130  | 0  |         case XML_COMMENT_NODE:  | 
3131  | 0  |       return(xmlStrdup(BAD_CAST "#comment"));  | 
3132  | 0  |         case XML_DOCUMENT_NODE:  | 
3133  | 0  |         case XML_HTML_DOCUMENT_NODE:  | 
3134  | 0  |       return(xmlStrdup(BAD_CAST "#document"));  | 
3135  | 0  |         case XML_DOCUMENT_FRAG_NODE:  | 
3136  | 0  |       return(xmlStrdup(BAD_CAST "#document-fragment"));  | 
3137  | 0  |         case XML_NOTATION_NODE:  | 
3138  | 0  |       return(xmlStrdup(node->name));  | 
3139  | 0  |         case XML_DOCUMENT_TYPE_NODE:  | 
3140  | 0  |         case XML_DTD_NODE:  | 
3141  | 0  |       return(xmlStrdup(node->name));  | 
3142  | 0  |         case XML_NAMESPACE_DECL: { | 
3143  | 0  |       xmlNsPtr ns = (xmlNsPtr) node;  | 
3144  |  | 
  | 
3145  | 0  |       ret = xmlStrdup(BAD_CAST "xmlns");  | 
3146  | 0  |       if (ns->prefix == NULL)  | 
3147  | 0  |     return(ret);  | 
3148  | 0  |       ret = xmlStrcat(ret, BAD_CAST ":");  | 
3149  | 0  |       ret = xmlStrcat(ret, ns->prefix);  | 
3150  | 0  |       return(ret);  | 
3151  | 0  |   }  | 
3152  |  |  | 
3153  | 0  |         case XML_ELEMENT_DECL:  | 
3154  | 0  |         case XML_ATTRIBUTE_DECL:  | 
3155  | 0  |         case XML_ENTITY_DECL:  | 
3156  | 0  |         case XML_XINCLUDE_START:  | 
3157  | 0  |         case XML_XINCLUDE_END:  | 
3158  | 0  |       return(NULL);  | 
3159  | 0  |     }  | 
3160  | 0  |     return(NULL);  | 
3161  | 0  | }  | 
3162  |  |  | 
3163  |  | /**  | 
3164  |  |  * xmlTextReaderConstName:  | 
3165  |  |  * @reader:  the xmlTextReaderPtr used  | 
3166  |  |  *  | 
3167  |  |  * The qualified name of the node, equal to Prefix :LocalName.  | 
3168  |  |  *  | 
3169  |  |  * Returns the local name or NULL if not available, the string is  | 
3170  |  |  *         deallocated with the reader.  | 
3171  |  |  */  | 
3172  |  | const xmlChar *  | 
3173  | 0  | xmlTextReaderConstName(xmlTextReaderPtr reader) { | 
3174  | 0  |     xmlNodePtr node;  | 
3175  |  | 
  | 
3176  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3177  | 0  |   return(NULL);  | 
3178  | 0  |     if (reader->curnode != NULL)  | 
3179  | 0  |   node = reader->curnode;  | 
3180  | 0  |     else  | 
3181  | 0  |   node = reader->node;  | 
3182  | 0  |     switch (node->type) { | 
3183  | 0  |         case XML_ELEMENT_NODE:  | 
3184  | 0  |         case XML_ATTRIBUTE_NODE:  | 
3185  | 0  |       if ((node->ns == NULL) ||  | 
3186  | 0  |     (node->ns->prefix == NULL))  | 
3187  | 0  |     return(node->name);  | 
3188  | 0  |       return(CONSTQSTR(node->ns->prefix, node->name));  | 
3189  | 0  |         case XML_TEXT_NODE:  | 
3190  | 0  |       return(CONSTSTR(BAD_CAST "#text"));  | 
3191  | 0  |         case XML_CDATA_SECTION_NODE:  | 
3192  | 0  |       return(CONSTSTR(BAD_CAST "#cdata-section"));  | 
3193  | 0  |         case XML_ENTITY_NODE:  | 
3194  | 0  |         case XML_ENTITY_REF_NODE:  | 
3195  | 0  |       return(CONSTSTR(node->name));  | 
3196  | 0  |         case XML_PI_NODE:  | 
3197  | 0  |       return(CONSTSTR(node->name));  | 
3198  | 0  |         case XML_COMMENT_NODE:  | 
3199  | 0  |       return(CONSTSTR(BAD_CAST "#comment"));  | 
3200  | 0  |         case XML_DOCUMENT_NODE:  | 
3201  | 0  |         case XML_HTML_DOCUMENT_NODE:  | 
3202  | 0  |       return(CONSTSTR(BAD_CAST "#document"));  | 
3203  | 0  |         case XML_DOCUMENT_FRAG_NODE:  | 
3204  | 0  |       return(CONSTSTR(BAD_CAST "#document-fragment"));  | 
3205  | 0  |         case XML_NOTATION_NODE:  | 
3206  | 0  |       return(CONSTSTR(node->name));  | 
3207  | 0  |         case XML_DOCUMENT_TYPE_NODE:  | 
3208  | 0  |         case XML_DTD_NODE:  | 
3209  | 0  |       return(CONSTSTR(node->name));  | 
3210  | 0  |         case XML_NAMESPACE_DECL: { | 
3211  | 0  |       xmlNsPtr ns = (xmlNsPtr) node;  | 
3212  |  | 
  | 
3213  | 0  |       if (ns->prefix == NULL)  | 
3214  | 0  |     return(CONSTSTR(BAD_CAST "xmlns"));  | 
3215  | 0  |       return(CONSTQSTR(BAD_CAST "xmlns", ns->prefix));  | 
3216  | 0  |   }  | 
3217  |  |  | 
3218  | 0  |         case XML_ELEMENT_DECL:  | 
3219  | 0  |         case XML_ATTRIBUTE_DECL:  | 
3220  | 0  |         case XML_ENTITY_DECL:  | 
3221  | 0  |         case XML_XINCLUDE_START:  | 
3222  | 0  |         case XML_XINCLUDE_END:  | 
3223  | 0  |       return(NULL);  | 
3224  | 0  |     }  | 
3225  | 0  |     return(NULL);  | 
3226  | 0  | }  | 
3227  |  |  | 
3228  |  | /**  | 
3229  |  |  * xmlTextReaderPrefix:  | 
3230  |  |  * @reader:  the xmlTextReaderPtr used  | 
3231  |  |  *  | 
3232  |  |  * A shorthand reference to the namespace associated with the node.  | 
3233  |  |  *  | 
3234  |  |  * Returns the prefix or NULL if not available,  | 
3235  |  |  *    if non NULL it need to be freed by the caller.  | 
3236  |  |  */  | 
3237  |  | xmlChar *  | 
3238  | 0  | xmlTextReaderPrefix(xmlTextReaderPtr reader) { | 
3239  | 0  |     xmlNodePtr node;  | 
3240  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3241  | 0  |   return(NULL);  | 
3242  | 0  |     if (reader->curnode != NULL)  | 
3243  | 0  |   node = reader->curnode;  | 
3244  | 0  |     else  | 
3245  | 0  |   node = reader->node;  | 
3246  | 0  |     if (node->type == XML_NAMESPACE_DECL) { | 
3247  | 0  |   xmlNsPtr ns = (xmlNsPtr) node;  | 
3248  | 0  |   if (ns->prefix == NULL)  | 
3249  | 0  |       return(NULL);  | 
3250  | 0  |   return(xmlStrdup(BAD_CAST "xmlns"));  | 
3251  | 0  |     }  | 
3252  | 0  |     if ((node->type != XML_ELEMENT_NODE) &&  | 
3253  | 0  |   (node->type != XML_ATTRIBUTE_NODE))  | 
3254  | 0  |   return(NULL);  | 
3255  | 0  |     if ((node->ns != NULL) && (node->ns->prefix != NULL))  | 
3256  | 0  |   return(xmlStrdup(node->ns->prefix));  | 
3257  | 0  |     return(NULL);  | 
3258  | 0  | }  | 
3259  |  |  | 
3260  |  | /**  | 
3261  |  |  * xmlTextReaderConstPrefix:  | 
3262  |  |  * @reader:  the xmlTextReaderPtr used  | 
3263  |  |  *  | 
3264  |  |  * A shorthand reference to the namespace associated with the node.  | 
3265  |  |  *  | 
3266  |  |  * Returns the prefix or NULL if not available, the string is deallocated  | 
3267  |  |  *         with the reader.  | 
3268  |  |  */  | 
3269  |  | const xmlChar *  | 
3270  | 0  | xmlTextReaderConstPrefix(xmlTextReaderPtr reader) { | 
3271  | 0  |     xmlNodePtr node;  | 
3272  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3273  | 0  |   return(NULL);  | 
3274  | 0  |     if (reader->curnode != NULL)  | 
3275  | 0  |   node = reader->curnode;  | 
3276  | 0  |     else  | 
3277  | 0  |   node = reader->node;  | 
3278  | 0  |     if (node->type == XML_NAMESPACE_DECL) { | 
3279  | 0  |   xmlNsPtr ns = (xmlNsPtr) node;  | 
3280  | 0  |   if (ns->prefix == NULL)  | 
3281  | 0  |       return(NULL);  | 
3282  | 0  |   return(CONSTSTR(BAD_CAST "xmlns"));  | 
3283  | 0  |     }  | 
3284  | 0  |     if ((node->type != XML_ELEMENT_NODE) &&  | 
3285  | 0  |   (node->type != XML_ATTRIBUTE_NODE))  | 
3286  | 0  |   return(NULL);  | 
3287  | 0  |     if ((node->ns != NULL) && (node->ns->prefix != NULL))  | 
3288  | 0  |   return(CONSTSTR(node->ns->prefix));  | 
3289  | 0  |     return(NULL);  | 
3290  | 0  | }  | 
3291  |  |  | 
3292  |  | /**  | 
3293  |  |  * xmlTextReaderNamespaceUri:  | 
3294  |  |  * @reader:  the xmlTextReaderPtr used  | 
3295  |  |  *  | 
3296  |  |  * The URI defining the namespace associated with the node.  | 
3297  |  |  *  | 
3298  |  |  * Returns the namespace URI or NULL if not available,  | 
3299  |  |  *    if non NULL it need to be freed by the caller.  | 
3300  |  |  */  | 
3301  |  | xmlChar *  | 
3302  | 0  | xmlTextReaderNamespaceUri(xmlTextReaderPtr reader) { | 
3303  | 0  |     xmlNodePtr node;  | 
3304  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3305  | 0  |   return(NULL);  | 
3306  | 0  |     if (reader->curnode != NULL)  | 
3307  | 0  |   node = reader->curnode;  | 
3308  | 0  |     else  | 
3309  | 0  |   node = reader->node;  | 
3310  | 0  |     if (node->type == XML_NAMESPACE_DECL)  | 
3311  | 0  |   return(xmlStrdup(BAD_CAST "http://www.w3.org/2000/xmlns/"));  | 
3312  | 0  |     if ((node->type != XML_ELEMENT_NODE) &&  | 
3313  | 0  |   (node->type != XML_ATTRIBUTE_NODE))  | 
3314  | 0  |   return(NULL);  | 
3315  | 0  |     if (node->ns != NULL)  | 
3316  | 0  |   return(xmlStrdup(node->ns->href));  | 
3317  | 0  |     return(NULL);  | 
3318  | 0  | }  | 
3319  |  |  | 
3320  |  | /**  | 
3321  |  |  * xmlTextReaderConstNamespaceUri:  | 
3322  |  |  * @reader:  the xmlTextReaderPtr used  | 
3323  |  |  *  | 
3324  |  |  * The URI defining the namespace associated with the node.  | 
3325  |  |  *  | 
3326  |  |  * Returns the namespace URI or NULL if not available, the string  | 
3327  |  |  *         will be deallocated with the reader  | 
3328  |  |  */  | 
3329  |  | const xmlChar *  | 
3330  | 0  | xmlTextReaderConstNamespaceUri(xmlTextReaderPtr reader) { | 
3331  | 0  |     xmlNodePtr node;  | 
3332  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3333  | 0  |   return(NULL);  | 
3334  | 0  |     if (reader->curnode != NULL)  | 
3335  | 0  |   node = reader->curnode;  | 
3336  | 0  |     else  | 
3337  | 0  |   node = reader->node;  | 
3338  | 0  |     if (node->type == XML_NAMESPACE_DECL)  | 
3339  | 0  |   return(CONSTSTR(BAD_CAST "http://www.w3.org/2000/xmlns/"));  | 
3340  | 0  |     if ((node->type != XML_ELEMENT_NODE) &&  | 
3341  | 0  |   (node->type != XML_ATTRIBUTE_NODE))  | 
3342  | 0  |   return(NULL);  | 
3343  | 0  |     if (node->ns != NULL)  | 
3344  | 0  |   return(CONSTSTR(node->ns->href));  | 
3345  | 0  |     return(NULL);  | 
3346  | 0  | }  | 
3347  |  |  | 
3348  |  | /**  | 
3349  |  |  * xmlTextReaderBaseUri:  | 
3350  |  |  * @reader:  the xmlTextReaderPtr used  | 
3351  |  |  *  | 
3352  |  |  * The base URI of the node.  | 
3353  |  |  *  | 
3354  |  |  * Returns the base URI or NULL if not available,  | 
3355  |  |  *    if non NULL it need to be freed by the caller.  | 
3356  |  |  */  | 
3357  |  | xmlChar *  | 
3358  | 0  | xmlTextReaderBaseUri(xmlTextReaderPtr reader) { | 
3359  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3360  | 0  |   return(NULL);  | 
3361  | 0  |     return(xmlNodeGetBase(NULL, reader->node));  | 
3362  | 0  | }  | 
3363  |  |  | 
3364  |  | /**  | 
3365  |  |  * xmlTextReaderConstBaseUri:  | 
3366  |  |  * @reader:  the xmlTextReaderPtr used  | 
3367  |  |  *  | 
3368  |  |  * The base URI of the node.  | 
3369  |  |  *  | 
3370  |  |  * Returns the base URI or NULL if not available, the string  | 
3371  |  |  *         will be deallocated with the reader  | 
3372  |  |  */  | 
3373  |  | const xmlChar *  | 
3374  | 0  | xmlTextReaderConstBaseUri(xmlTextReaderPtr reader) { | 
3375  | 0  |     xmlChar *tmp;  | 
3376  | 0  |     const xmlChar *ret;  | 
3377  |  | 
  | 
3378  | 0  |     if ((reader == NULL) || (reader->node == NULL))  | 
3379  | 0  |   return(NULL);  | 
3380  | 0  |     tmp = xmlNodeGetBase(NULL, reader->node);  | 
3381  | 0  |     if (tmp == NULL)  | 
3382  | 0  |         return(NULL);  | 
3383  | 0  |     ret = CONSTSTR(tmp);  | 
3384  | 0  |     xmlFree(tmp);  | 
3385  | 0  |     return(ret);  | 
3386  | 0  | }  | 
3387  |  |  | 
3388  |  | /**  | 
3389  |  |  * xmlTextReaderDepth:  | 
3390  |  |  * @reader:  the xmlTextReaderPtr used  | 
3391  |  |  *  | 
3392  |  |  * The depth of the node in the tree.  | 
3393  |  |  *  | 
3394  |  |  * Returns the depth or -1 in case of error  | 
3395  |  |  */  | 
3396  |  | int  | 
3397  | 0  | xmlTextReaderDepth(xmlTextReaderPtr reader) { | 
3398  | 0  |     if (reader == NULL)  | 
3399  | 0  |   return(-1);  | 
3400  | 0  |     if (reader->node == NULL)  | 
3401  | 0  |   return(0);  | 
3402  |  |  | 
3403  | 0  |     if (reader->curnode != NULL) { | 
3404  | 0  |   if ((reader->curnode->type == XML_ATTRIBUTE_NODE) ||  | 
3405  | 0  |       (reader->curnode->type == XML_NAMESPACE_DECL))  | 
3406  | 0  |       return(reader->depth + 1);  | 
3407  | 0  |   return(reader->depth + 2);  | 
3408  | 0  |     }  | 
3409  | 0  |     return(reader->depth);  | 
3410  | 0  | }  | 
3411  |  |  | 
3412  |  | /**  | 
3413  |  |  * xmlTextReaderHasAttributes:  | 
3414  |  |  * @reader:  the xmlTextReaderPtr used  | 
3415  |  |  *  | 
3416  |  |  * Whether the node has attributes.  | 
3417  |  |  *  | 
3418  |  |  * Returns 1 if true, 0 if false, and -1 in case or error  | 
3419  |  |  */  | 
3420  |  | int  | 
3421  | 0  | xmlTextReaderHasAttributes(xmlTextReaderPtr reader) { | 
3422  | 0  |     xmlNodePtr node;  | 
3423  | 0  |     if (reader == NULL)  | 
3424  | 0  |   return(-1);  | 
3425  | 0  |     if (reader->node == NULL)  | 
3426  | 0  |   return(0);  | 
3427  | 0  |     if (reader->curnode != NULL)  | 
3428  | 0  |   node = reader->curnode;  | 
3429  | 0  |     else  | 
3430  | 0  |   node = reader->node;  | 
3431  |  | 
  | 
3432  | 0  |     if ((node->type == XML_ELEMENT_NODE) &&  | 
3433  | 0  |   ((node->properties != NULL) || (node->nsDef != NULL)))  | 
3434  | 0  |   return(1);  | 
3435  |  |     /* TODO: handle the xmlDecl */  | 
3436  | 0  |     return(0);  | 
3437  | 0  | }  | 
3438  |  |  | 
3439  |  | /**  | 
3440  |  |  * xmlTextReaderHasValue:  | 
3441  |  |  * @reader:  the xmlTextReaderPtr used  | 
3442  |  |  *  | 
3443  |  |  * Whether the node can have a text value.  | 
3444  |  |  *  | 
3445  |  |  * Returns 1 if true, 0 if false, and -1 in case or error  | 
3446  |  |  */  | 
3447  |  | int  | 
3448  | 0  | xmlTextReaderHasValue(xmlTextReaderPtr reader) { | 
3449  | 0  |     xmlNodePtr node;  | 
3450  | 0  |     if (reader == NULL)  | 
3451  | 0  |   return(-1);  | 
3452  | 0  |     if (reader->node == NULL)  | 
3453  | 0  |   return(0);  | 
3454  | 0  |     if (reader->curnode != NULL)  | 
3455  | 0  |   node = reader->curnode;  | 
3456  | 0  |     else  | 
3457  | 0  |   node = reader->node;  | 
3458  |  | 
  | 
3459  | 0  |     switch (node->type) { | 
3460  | 0  |         case XML_ATTRIBUTE_NODE:  | 
3461  | 0  |         case XML_TEXT_NODE:  | 
3462  | 0  |         case XML_CDATA_SECTION_NODE:  | 
3463  | 0  |         case XML_PI_NODE:  | 
3464  | 0  |         case XML_COMMENT_NODE:  | 
3465  | 0  |         case XML_NAMESPACE_DECL:  | 
3466  | 0  |       return(1);  | 
3467  | 0  |   default:  | 
3468  | 0  |       break;  | 
3469  | 0  |     }  | 
3470  | 0  |     return(0);  | 
3471  | 0  | }  | 
3472  |  |  | 
3473  |  | /**  | 
3474  |  |  * xmlTextReaderValue:  | 
3475  |  |  * @reader:  the xmlTextReaderPtr used  | 
3476  |  |  *  | 
3477  |  |  * Provides the text value of the node if present  | 
3478  |  |  *  | 
3479  |  |  * Returns the string or NULL if not available. The result must be deallocated  | 
3480  |  |  *     with xmlFree()  | 
3481  |  |  */  | 
3482  |  | xmlChar *  | 
3483  | 0  | xmlTextReaderValue(xmlTextReaderPtr reader) { | 
3484  | 0  |     xmlNodePtr node;  | 
3485  | 0  |     if (reader == NULL)  | 
3486  | 0  |   return(NULL);  | 
3487  | 0  |     if (reader->node == NULL)  | 
3488  | 0  |   return(NULL);  | 
3489  | 0  |     if (reader->curnode != NULL)  | 
3490  | 0  |   node = reader->curnode;  | 
3491  | 0  |     else  | 
3492  | 0  |   node = reader->node;  | 
3493  |  | 
  | 
3494  | 0  |     switch (node->type) { | 
3495  | 0  |         case XML_NAMESPACE_DECL:  | 
3496  | 0  |       return(xmlStrdup(((xmlNsPtr) node)->href));  | 
3497  | 0  |         case XML_ATTRIBUTE_NODE:{ | 
3498  | 0  |       xmlAttrPtr attr = (xmlAttrPtr) node;  | 
3499  |  | 
  | 
3500  | 0  |       if (attr->parent != NULL)  | 
3501  | 0  |     return (xmlNodeListGetString  | 
3502  | 0  |       (attr->parent->doc, attr->children, 1));  | 
3503  | 0  |       else  | 
3504  | 0  |     return (xmlNodeListGetString(NULL, attr->children, 1));  | 
3505  | 0  |       break;  | 
3506  | 0  |   }  | 
3507  | 0  |         case XML_TEXT_NODE:  | 
3508  | 0  |         case XML_CDATA_SECTION_NODE:  | 
3509  | 0  |         case XML_PI_NODE:  | 
3510  | 0  |         case XML_COMMENT_NODE:  | 
3511  | 0  |             if (node->content != NULL)  | 
3512  | 0  |                 return (xmlStrdup(node->content));  | 
3513  | 0  |   default:  | 
3514  | 0  |       break;  | 
3515  | 0  |     }  | 
3516  | 0  |     return(NULL);  | 
3517  | 0  | }  | 
3518  |  |  | 
3519  |  | /**  | 
3520  |  |  * xmlTextReaderConstValue:  | 
3521  |  |  * @reader:  the xmlTextReaderPtr used  | 
3522  |  |  *  | 
3523  |  |  * Provides the text value of the node if present  | 
3524  |  |  *  | 
3525  |  |  * Returns the string or NULL if not available. The result will be  | 
3526  |  |  *     deallocated on the next Read() operation.  | 
3527  |  |  */  | 
3528  |  | const xmlChar *  | 
3529  | 0  | xmlTextReaderConstValue(xmlTextReaderPtr reader) { | 
3530  | 0  |     xmlNodePtr node;  | 
3531  | 0  |     if (reader == NULL)  | 
3532  | 0  |   return(NULL);  | 
3533  | 0  |     if (reader->node == NULL)  | 
3534  | 0  |   return(NULL);  | 
3535  | 0  |     if (reader->curnode != NULL)  | 
3536  | 0  |   node = reader->curnode;  | 
3537  | 0  |     else  | 
3538  | 0  |   node = reader->node;  | 
3539  |  | 
  | 
3540  | 0  |     switch (node->type) { | 
3541  | 0  |         case XML_NAMESPACE_DECL:  | 
3542  | 0  |       return(((xmlNsPtr) node)->href);  | 
3543  | 0  |         case XML_ATTRIBUTE_NODE:{ | 
3544  | 0  |       xmlAttrPtr attr = (xmlAttrPtr) node;  | 
3545  | 0  |       const xmlChar *ret;  | 
3546  |  | 
  | 
3547  | 0  |       if ((attr->children != NULL) &&  | 
3548  | 0  |           (attr->children->type == XML_TEXT_NODE) &&  | 
3549  | 0  |     (attr->children->next == NULL))  | 
3550  | 0  |     return(attr->children->content);  | 
3551  | 0  |       else { | 
3552  | 0  |     if (reader->buffer == NULL) { | 
3553  | 0  |         reader->buffer = xmlBufCreateSize(100);  | 
3554  | 0  |                     if (reader->buffer == NULL) { | 
3555  | 0  |                         xmlGenericError(xmlGenericErrorContext,  | 
3556  | 0  |                                         "xmlTextReaderSetup : malloc failed\n");  | 
3557  | 0  |                         return (NULL);  | 
3558  | 0  |                     }  | 
3559  | 0  |         xmlBufSetAllocationScheme(reader->buffer,  | 
3560  | 0  |                                   XML_BUFFER_ALLOC_DOUBLEIT);  | 
3561  | 0  |                 } else  | 
3562  | 0  |                     xmlBufEmpty(reader->buffer);  | 
3563  | 0  |           xmlBufGetNodeContent(reader->buffer, node);  | 
3564  | 0  |     ret = xmlBufContent(reader->buffer);  | 
3565  | 0  |     if (ret == NULL) { | 
3566  |  |         /* error on the buffer best to reallocate */  | 
3567  | 0  |         xmlBufFree(reader->buffer);  | 
3568  | 0  |         reader->buffer = xmlBufCreateSize(100);  | 
3569  | 0  |         xmlBufSetAllocationScheme(reader->buffer,  | 
3570  | 0  |                                   XML_BUFFER_ALLOC_DOUBLEIT);  | 
3571  | 0  |         ret = BAD_CAST "";  | 
3572  | 0  |     }  | 
3573  | 0  |     return(ret);  | 
3574  | 0  |       }  | 
3575  | 0  |       break;  | 
3576  | 0  |   }  | 
3577  | 0  |         case XML_TEXT_NODE:  | 
3578  | 0  |         case XML_CDATA_SECTION_NODE:  | 
3579  | 0  |         case XML_PI_NODE:  | 
3580  | 0  |         case XML_COMMENT_NODE:  | 
3581  | 0  |       return(node->content);  | 
3582  | 0  |   default:  | 
3583  | 0  |       break;  | 
3584  | 0  |     }  | 
3585  | 0  |     return(NULL);  | 
3586  | 0  | }  | 
3587  |  |  | 
3588  |  | /**  | 
3589  |  |  * xmlTextReaderIsDefault:  | 
3590  |  |  * @reader:  the xmlTextReaderPtr used  | 
3591  |  |  *  | 
3592  |  |  * Whether an Attribute  node was generated from the default value  | 
3593  |  |  * defined in the DTD or schema.  | 
3594  |  |  *  | 
3595  |  |  * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error  | 
3596  |  |  */  | 
3597  |  | int  | 
3598  | 0  | xmlTextReaderIsDefault(xmlTextReaderPtr reader) { | 
3599  | 0  |     if (reader == NULL)  | 
3600  | 0  |   return(-1);  | 
3601  | 0  |     return(0);  | 
3602  | 0  | }  | 
3603  |  |  | 
3604  |  | /**  | 
3605  |  |  * xmlTextReaderQuoteChar:  | 
3606  |  |  * @reader:  the xmlTextReaderPtr used  | 
3607  |  |  *  | 
3608  |  |  * The quotation mark character used to enclose the value of an attribute.  | 
3609  |  |  *  | 
3610  |  |  * Returns " or ' and -1 in case of error  | 
3611  |  |  */  | 
3612  |  | int  | 
3613  | 0  | xmlTextReaderQuoteChar(xmlTextReaderPtr reader) { | 
3614  | 0  |     if (reader == NULL)  | 
3615  | 0  |   return(-1);  | 
3616  |  |     /* TODO maybe lookup the attribute value for " first */  | 
3617  | 0  |     return('"'); | 
3618  | 0  | }  | 
3619  |  |  | 
3620  |  | /**  | 
3621  |  |  * xmlTextReaderXmlLang:  | 
3622  |  |  * @reader:  the xmlTextReaderPtr used  | 
3623  |  |  *  | 
3624  |  |  * The xml:lang scope within which the node resides.  | 
3625  |  |  *  | 
3626  |  |  * Returns the xml:lang value or NULL if none exists.,  | 
3627  |  |  *    if non NULL it need to be freed by the caller.  | 
3628  |  |  */  | 
3629  |  | xmlChar *  | 
3630  | 0  | xmlTextReaderXmlLang(xmlTextReaderPtr reader) { | 
3631  | 0  |     if (reader == NULL)  | 
3632  | 0  |   return(NULL);  | 
3633  | 0  |     if (reader->node == NULL)  | 
3634  | 0  |   return(NULL);  | 
3635  | 0  |     return(xmlNodeGetLang(reader->node));  | 
3636  | 0  | }  | 
3637  |  |  | 
3638  |  | /**  | 
3639  |  |  * xmlTextReaderConstXmlLang:  | 
3640  |  |  * @reader:  the xmlTextReaderPtr used  | 
3641  |  |  *  | 
3642  |  |  * The xml:lang scope within which the node resides.  | 
3643  |  |  *  | 
3644  |  |  * Returns the xml:lang value or NULL if none exists.  | 
3645  |  |  */  | 
3646  |  | const xmlChar *  | 
3647  | 0  | xmlTextReaderConstXmlLang(xmlTextReaderPtr reader) { | 
3648  | 0  |     xmlChar *tmp;  | 
3649  | 0  |     const xmlChar *ret;  | 
3650  |  | 
  | 
3651  | 0  |     if (reader == NULL)  | 
3652  | 0  |   return(NULL);  | 
3653  | 0  |     if (reader->node == NULL)  | 
3654  | 0  |   return(NULL);  | 
3655  | 0  |     tmp = xmlNodeGetLang(reader->node);  | 
3656  | 0  |     if (tmp == NULL)  | 
3657  | 0  |         return(NULL);  | 
3658  | 0  |     ret = CONSTSTR(tmp);  | 
3659  | 0  |     xmlFree(tmp);  | 
3660  | 0  |     return(ret);  | 
3661  | 0  | }  | 
3662  |  |  | 
3663  |  | /**  | 
3664  |  |  * xmlTextReaderConstString:  | 
3665  |  |  * @reader:  the xmlTextReaderPtr used  | 
3666  |  |  * @str:  the string to intern.  | 
3667  |  |  *  | 
3668  |  |  * Get an interned string from the reader, allows for example to  | 
3669  |  |  * speedup string name comparisons  | 
3670  |  |  *  | 
3671  |  |  * Returns an interned copy of the string or NULL in case of error. The  | 
3672  |  |  *         string will be deallocated with the reader.  | 
3673  |  |  */  | 
3674  |  | const xmlChar *  | 
3675  | 0  | xmlTextReaderConstString(xmlTextReaderPtr reader, const xmlChar *str) { | 
3676  | 0  |     if (reader == NULL)  | 
3677  | 0  |   return(NULL);  | 
3678  | 0  |     return(CONSTSTR(str));  | 
3679  | 0  | }  | 
3680  |  |  | 
3681  |  | /**  | 
3682  |  |  * xmlTextReaderNormalization:  | 
3683  |  |  * @reader:  the xmlTextReaderPtr used  | 
3684  |  |  *  | 
3685  |  |  * The value indicating whether to normalize white space and attribute values.  | 
3686  |  |  * Since attribute value and end of line normalizations are a MUST in the XML  | 
3687  |  |  * specification only the value true is accepted. The broken behaviour of  | 
3688  |  |  * accepting out of range character entities like � is of course not  | 
3689  |  |  * supported either.  | 
3690  |  |  *  | 
3691  |  |  * Returns 1 or -1 in case of error.  | 
3692  |  |  */  | 
3693  |  | int  | 
3694  | 0  | xmlTextReaderNormalization(xmlTextReaderPtr reader) { | 
3695  | 0  |     if (reader == NULL)  | 
3696  | 0  |   return(-1);  | 
3697  | 0  |     return(1);  | 
3698  | 0  | }  | 
3699  |  |  | 
3700  |  | /************************************************************************  | 
3701  |  |  *                  *  | 
3702  |  |  *      Extensions to the base APIs     *  | 
3703  |  |  *                  *  | 
3704  |  |  ************************************************************************/  | 
3705  |  |  | 
3706  |  | /**  | 
3707  |  |  * xmlTextReaderSetParserProp:  | 
3708  |  |  * @reader:  the xmlTextReaderPtr used  | 
3709  |  |  * @prop:  the xmlParserProperties to set  | 
3710  |  |  * @value:  usually 0 or 1 to (de)activate it  | 
3711  |  |  *  | 
3712  |  |  * Change the parser processing behaviour by changing some of its internal  | 
3713  |  |  * properties. Note that some properties can only be changed before any  | 
3714  |  |  * read has been done.  | 
3715  |  |  *  | 
3716  |  |  * Returns 0 if the call was successful, or -1 in case of error  | 
3717  |  |  */  | 
3718  |  | int  | 
3719  | 0  | xmlTextReaderSetParserProp(xmlTextReaderPtr reader, int prop, int value) { | 
3720  | 0  |     xmlParserProperties p = (xmlParserProperties) prop;  | 
3721  | 0  |     xmlParserCtxtPtr ctxt;  | 
3722  |  | 
  | 
3723  | 0  |     if ((reader == NULL) || (reader->ctxt == NULL))  | 
3724  | 0  |   return(-1);  | 
3725  | 0  |     ctxt = reader->ctxt;  | 
3726  |  | 
  | 
3727  | 0  |     switch (p) { | 
3728  | 0  |         case XML_PARSER_LOADDTD:  | 
3729  | 0  |       if (value != 0) { | 
3730  | 0  |     if (ctxt->loadsubset == 0) { | 
3731  | 0  |         if (reader->mode != XML_TEXTREADER_MODE_INITIAL)  | 
3732  | 0  |       return(-1);  | 
3733  | 0  |         ctxt->loadsubset = XML_DETECT_IDS;  | 
3734  | 0  |     }  | 
3735  | 0  |       } else { | 
3736  | 0  |     ctxt->loadsubset = 0;  | 
3737  | 0  |       }  | 
3738  | 0  |       return(0);  | 
3739  | 0  |         case XML_PARSER_DEFAULTATTRS:  | 
3740  | 0  |       if (value != 0) { | 
3741  | 0  |     ctxt->loadsubset |= XML_COMPLETE_ATTRS;  | 
3742  | 0  |       } else { | 
3743  | 0  |     if (ctxt->loadsubset & XML_COMPLETE_ATTRS)  | 
3744  | 0  |         ctxt->loadsubset -= XML_COMPLETE_ATTRS;  | 
3745  | 0  |       }  | 
3746  | 0  |       return(0);  | 
3747  | 0  |         case XML_PARSER_VALIDATE:  | 
3748  | 0  |       if (value != 0) { | 
3749  | 0  |                 ctxt->options |= XML_PARSE_DTDVALID;  | 
3750  | 0  |     ctxt->validate = 1;  | 
3751  | 0  |     reader->validate = XML_TEXTREADER_VALIDATE_DTD;  | 
3752  | 0  |       } else { | 
3753  | 0  |                 ctxt->options &= ~XML_PARSE_DTDVALID;  | 
3754  | 0  |     ctxt->validate = 0;  | 
3755  | 0  |       }  | 
3756  | 0  |       return(0);  | 
3757  | 0  |         case XML_PARSER_SUBST_ENTITIES:  | 
3758  | 0  |       if (value != 0) { | 
3759  | 0  |                 ctxt->options |= XML_PARSE_NOENT;  | 
3760  | 0  |     ctxt->replaceEntities = 1;  | 
3761  | 0  |       } else { | 
3762  | 0  |                 ctxt->options &= ~XML_PARSE_NOENT;  | 
3763  | 0  |     ctxt->replaceEntities = 0;  | 
3764  | 0  |       }  | 
3765  | 0  |       return(0);  | 
3766  | 0  |     }  | 
3767  | 0  |     return(-1);  | 
3768  | 0  | }  | 
3769  |  |  | 
3770  |  | /**  | 
3771  |  |  * xmlTextReaderGetParserProp:  | 
3772  |  |  * @reader:  the xmlTextReaderPtr used  | 
3773  |  |  * @prop:  the xmlParserProperties to get  | 
3774  |  |  *  | 
3775  |  |  * Read the parser internal property.  | 
3776  |  |  *  | 
3777  |  |  * Returns the value, usually 0 or 1, or -1 in case of error.  | 
3778  |  |  */  | 
3779  |  | int  | 
3780  | 0  | xmlTextReaderGetParserProp(xmlTextReaderPtr reader, int prop) { | 
3781  | 0  |     xmlParserProperties p = (xmlParserProperties) prop;  | 
3782  | 0  |     xmlParserCtxtPtr ctxt;  | 
3783  |  | 
  | 
3784  | 0  |     if ((reader == NULL) || (reader->ctxt == NULL))  | 
3785  | 0  |   return(-1);  | 
3786  | 0  |     ctxt = reader->ctxt;  | 
3787  |  | 
  | 
3788  | 0  |     switch (p) { | 
3789  | 0  |         case XML_PARSER_LOADDTD:  | 
3790  | 0  |       if ((ctxt->loadsubset != 0) || (ctxt->validate != 0))  | 
3791  | 0  |     return(1);  | 
3792  | 0  |       return(0);  | 
3793  | 0  |         case XML_PARSER_DEFAULTATTRS:  | 
3794  | 0  |       if (ctxt->loadsubset & XML_COMPLETE_ATTRS)  | 
3795  | 0  |     return(1);  | 
3796  | 0  |       return(0);  | 
3797  | 0  |         case XML_PARSER_VALIDATE:  | 
3798  | 0  |       return(reader->validate);  | 
3799  | 0  |   case XML_PARSER_SUBST_ENTITIES:  | 
3800  | 0  |       return(ctxt->replaceEntities);  | 
3801  | 0  |     }  | 
3802  | 0  |     return(-1);  | 
3803  | 0  | }  | 
3804  |  |  | 
3805  |  |  | 
3806  |  | /**  | 
3807  |  |  * xmlTextReaderGetParserLineNumber:  | 
3808  |  |  * @reader: the user data (XML reader context)  | 
3809  |  |  *  | 
3810  |  |  * Provide the line number of the current parsing point.  | 
3811  |  |  *  | 
3812  |  |  * Returns an int or 0 if not available  | 
3813  |  |  */  | 
3814  |  | int  | 
3815  |  | xmlTextReaderGetParserLineNumber(xmlTextReaderPtr reader)  | 
3816  | 0  | { | 
3817  | 0  |     if ((reader == NULL) || (reader->ctxt == NULL) ||  | 
3818  | 0  |         (reader->ctxt->input == NULL)) { | 
3819  | 0  |         return (0);  | 
3820  | 0  |     }  | 
3821  | 0  |     return (reader->ctxt->input->line);  | 
3822  | 0  | }  | 
3823  |  |  | 
3824  |  | /**  | 
3825  |  |  * xmlTextReaderGetParserColumnNumber:  | 
3826  |  |  * @reader: the user data (XML reader context)  | 
3827  |  |  *  | 
3828  |  |  * Provide the column number of the current parsing point.  | 
3829  |  |  *  | 
3830  |  |  * Returns an int or 0 if not available  | 
3831  |  |  */  | 
3832  |  | int  | 
3833  |  | xmlTextReaderGetParserColumnNumber(xmlTextReaderPtr reader)  | 
3834  | 0  | { | 
3835  | 0  |     if ((reader == NULL) || (reader->ctxt == NULL) ||  | 
3836  | 0  |         (reader->ctxt->input == NULL)) { | 
3837  | 0  |         return (0);  | 
3838  | 0  |     }  | 
3839  | 0  |     return (reader->ctxt->input->col);  | 
3840  | 0  | }  | 
3841  |  |  | 
3842  |  | /**  | 
3843  |  |  * xmlTextReaderCurrentNode:  | 
3844  |  |  * @reader:  the xmlTextReaderPtr used  | 
3845  |  |  *  | 
3846  |  |  * Hacking interface allowing to get the xmlNodePtr corresponding to the  | 
3847  |  |  * current node being accessed by the xmlTextReader. This is dangerous  | 
3848  |  |  * because the underlying node may be destroyed on the next Reads.  | 
3849  |  |  *  | 
3850  |  |  * Returns the xmlNodePtr or NULL in case of error.  | 
3851  |  |  */  | 
3852  |  | xmlNodePtr  | 
3853  | 0  | xmlTextReaderCurrentNode(xmlTextReaderPtr reader) { | 
3854  | 0  |     if (reader == NULL)  | 
3855  | 0  |   return(NULL);  | 
3856  |  |  | 
3857  | 0  |     if (reader->curnode != NULL)  | 
3858  | 0  |   return(reader->curnode);  | 
3859  | 0  |     return(reader->node);  | 
3860  | 0  | }  | 
3861  |  |  | 
3862  |  | /**  | 
3863  |  |  * xmlTextReaderPreserve:  | 
3864  |  |  * @reader:  the xmlTextReaderPtr used  | 
3865  |  |  *  | 
3866  |  |  * This tells the XML Reader to preserve the current node.  | 
3867  |  |  * The caller must also use xmlTextReaderCurrentDoc() to  | 
3868  |  |  * keep an handle on the resulting document once parsing has finished  | 
3869  |  |  *  | 
3870  |  |  * Returns the xmlNodePtr or NULL in case of error.  | 
3871  |  |  */  | 
3872  |  | xmlNodePtr  | 
3873  | 0  | xmlTextReaderPreserve(xmlTextReaderPtr reader) { | 
3874  | 0  |     xmlNodePtr cur, parent;  | 
3875  |  | 
  | 
3876  | 0  |     if (reader == NULL)  | 
3877  | 0  |   return(NULL);  | 
3878  |  |  | 
3879  | 0  |     if (reader->curnode != NULL)  | 
3880  | 0  |         cur = reader->curnode;  | 
3881  | 0  |     else  | 
3882  | 0  |         cur = reader->node;  | 
3883  | 0  |     if (cur == NULL)  | 
3884  | 0  |         return(NULL);  | 
3885  |  |  | 
3886  | 0  |     if ((cur->type != XML_DOCUMENT_NODE) && (cur->type != XML_DTD_NODE)) { | 
3887  | 0  |   cur->extra |= NODE_IS_PRESERVED;  | 
3888  | 0  |   cur->extra |= NODE_IS_SPRESERVED;  | 
3889  | 0  |     }  | 
3890  | 0  |     reader->preserves++;  | 
3891  |  | 
  | 
3892  | 0  |     parent = cur->parent;;  | 
3893  | 0  |     while (parent != NULL) { | 
3894  | 0  |         if (parent->type == XML_ELEMENT_NODE)  | 
3895  | 0  |       parent->extra |= NODE_IS_PRESERVED;  | 
3896  | 0  |   parent = parent->parent;  | 
3897  | 0  |     }  | 
3898  | 0  |     return(cur);  | 
3899  | 0  | }  | 
3900  |  |  | 
3901  |  | #ifdef LIBXML_PATTERN_ENABLED  | 
3902  |  | /**  | 
3903  |  |  * xmlTextReaderPreservePattern:  | 
3904  |  |  * @reader:  the xmlTextReaderPtr used  | 
3905  |  |  * @pattern:  an XPath subset pattern  | 
3906  |  |  * @namespaces: the prefix definitions, array of [URI, prefix] or NULL  | 
3907  |  |  *  | 
3908  |  |  * This tells the XML Reader to preserve all nodes matched by the  | 
3909  |  |  * pattern. The caller must also use xmlTextReaderCurrentDoc() to  | 
3910  |  |  * keep an handle on the resulting document once parsing has finished  | 
3911  |  |  *  | 
3912  |  |  * Returns a non-negative number in case of success and -1 in case of error  | 
3913  |  |  */  | 
3914  |  | int  | 
3915  |  | xmlTextReaderPreservePattern(xmlTextReaderPtr reader, const xmlChar *pattern,  | 
3916  |  |                              const xmlChar **namespaces)  | 
3917  | 0  | { | 
3918  | 0  |     xmlPatternPtr comp;  | 
3919  |  | 
  | 
3920  | 0  |     if ((reader == NULL) || (pattern == NULL))  | 
3921  | 0  |   return(-1);  | 
3922  |  |  | 
3923  | 0  |     comp = xmlPatterncompile(pattern, reader->dict, 0, namespaces);  | 
3924  | 0  |     if (comp == NULL)  | 
3925  | 0  |         return(-1);  | 
3926  |  |  | 
3927  | 0  |     if (reader->patternMax <= 0) { | 
3928  | 0  |   reader->patternMax = 4;  | 
3929  | 0  |   reader->patternTab = (xmlPatternPtr *) xmlMalloc(reader->patternMax *  | 
3930  | 0  |                 sizeof(reader->patternTab[0]));  | 
3931  | 0  |         if (reader->patternTab == NULL) { | 
3932  | 0  |             xmlGenericError(xmlGenericErrorContext, "xmlMalloc failed !\n");  | 
3933  | 0  |             return (-1);  | 
3934  | 0  |         }  | 
3935  | 0  |     }  | 
3936  | 0  |     if (reader->patternNr >= reader->patternMax) { | 
3937  | 0  |         xmlPatternPtr *tmp;  | 
3938  | 0  |         reader->patternMax *= 2;  | 
3939  | 0  |   tmp = (xmlPatternPtr *) xmlRealloc(reader->patternTab,  | 
3940  | 0  |                                       reader->patternMax *  | 
3941  | 0  |                                       sizeof(reader->patternTab[0]));  | 
3942  | 0  |         if (tmp == NULL) { | 
3943  | 0  |             xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");  | 
3944  | 0  |       reader->patternMax /= 2;  | 
3945  | 0  |             return (-1);  | 
3946  | 0  |         }  | 
3947  | 0  |   reader->patternTab = tmp;  | 
3948  | 0  |     }  | 
3949  | 0  |     reader->patternTab[reader->patternNr] = comp;  | 
3950  | 0  |     return(reader->patternNr++);  | 
3951  | 0  | }  | 
3952  |  | #endif  | 
3953  |  |  | 
3954  |  | /**  | 
3955  |  |  * xmlTextReaderCurrentDoc:  | 
3956  |  |  * @reader:  the xmlTextReaderPtr used  | 
3957  |  |  *  | 
3958  |  |  * Hacking interface allowing to get the xmlDocPtr corresponding to the  | 
3959  |  |  * current document being accessed by the xmlTextReader.  | 
3960  |  |  * NOTE: as a result of this call, the reader will not destroy the  | 
3961  |  |  *       associated XML document and calling xmlFreeDoc() on the result  | 
3962  |  |  *       is needed once the reader parsing has finished.  | 
3963  |  |  *  | 
3964  |  |  * Returns the xmlDocPtr or NULL in case of error.  | 
3965  |  |  */  | 
3966  |  | xmlDocPtr  | 
3967  | 0  | xmlTextReaderCurrentDoc(xmlTextReaderPtr reader) { | 
3968  | 0  |     if (reader == NULL)  | 
3969  | 0  |   return(NULL);  | 
3970  | 0  |     if (reader->doc != NULL)  | 
3971  | 0  |         return(reader->doc);  | 
3972  | 0  |     if ((reader->ctxt == NULL) || (reader->ctxt->myDoc == NULL))  | 
3973  | 0  |   return(NULL);  | 
3974  |  |  | 
3975  | 0  |     reader->preserve = 1;  | 
3976  | 0  |     return(reader->ctxt->myDoc);  | 
3977  | 0  | }  | 
3978  |  |  | 
3979  |  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
3980  |  | static char *xmlTextReaderBuildMessage(const char *msg, va_list ap) LIBXML_ATTR_FORMAT(1,0);  | 
3981  |  |  | 
3982  |  | static void  | 
3983  |  | xmlTextReaderValidityError(void *ctxt, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);  | 
3984  |  |  | 
3985  |  | static void  | 
3986  |  | xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);  | 
3987  |  |  | 
3988  |  | static void  | 
3989  |  | xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);  | 
3990  |  |  | 
3991  |  | static void  | 
3992  |  | xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);  | 
3993  |  |  | 
3994  |  | static void  | 
3995  |  | xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)  | 
3996  | 0  | { | 
3997  | 0  |     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;  | 
3998  |  | 
  | 
3999  | 0  |     char *str;  | 
4000  |  | 
  | 
4001  | 0  |     va_list ap;  | 
4002  |  | 
  | 
4003  | 0  |     va_start(ap, msg);  | 
4004  | 0  |     str = xmlTextReaderBuildMessage(msg, ap);  | 
4005  | 0  |     if (!reader->errorFunc) { | 
4006  | 0  |         xmlTextReaderValidityError(ctx, "%s", str);  | 
4007  | 0  |     } else { | 
4008  | 0  |         reader->errorFunc(reader->errorFuncArg, str,  | 
4009  | 0  |                           XML_PARSER_SEVERITY_VALIDITY_ERROR,  | 
4010  | 0  |                           NULL /* locator */ );  | 
4011  | 0  |     }  | 
4012  | 0  |     if (str != NULL)  | 
4013  | 0  |         xmlFree(str);  | 
4014  | 0  |     va_end(ap);  | 
4015  | 0  | }  | 
4016  |  |  | 
4017  |  | static void  | 
4018  |  | xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...)  | 
4019  | 0  | { | 
4020  | 0  |     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;  | 
4021  |  | 
  | 
4022  | 0  |     char *str;  | 
4023  |  | 
  | 
4024  | 0  |     va_list ap;  | 
4025  |  | 
  | 
4026  | 0  |     va_start(ap, msg);  | 
4027  | 0  |     str = xmlTextReaderBuildMessage(msg, ap);  | 
4028  | 0  |     if (!reader->errorFunc) { | 
4029  | 0  |         xmlTextReaderValidityWarning(ctx, "%s", str);  | 
4030  | 0  |     } else { | 
4031  | 0  |         reader->errorFunc(reader->errorFuncArg, str,  | 
4032  | 0  |                           XML_PARSER_SEVERITY_VALIDITY_WARNING,  | 
4033  | 0  |                           NULL /* locator */ );  | 
4034  | 0  |     }  | 
4035  | 0  |     if (str != NULL)  | 
4036  | 0  |         xmlFree(str);  | 
4037  | 0  |     va_end(ap);  | 
4038  | 0  | }  | 
4039  |  |  | 
4040  |  | static void  | 
4041  |  |   xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error);  | 
4042  |  |  | 
4043  |  | static void  | 
4044  |  | xmlTextReaderValidityStructuredRelay(void *userData, xmlErrorPtr error)  | 
4045  | 0  | { | 
4046  | 0  |     xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;  | 
4047  |  | 
  | 
4048  | 0  |     if (reader->sErrorFunc) { | 
4049  | 0  |         reader->sErrorFunc(reader->errorFuncArg, error);  | 
4050  | 0  |     } else { | 
4051  | 0  |         xmlTextReaderStructuredError(reader, error);  | 
4052  | 0  |     }  | 
4053  | 0  | }  | 
4054  |  | /**  | 
4055  |  |  * xmlTextReaderRelaxNGSetSchema:  | 
4056  |  |  * @reader:  the xmlTextReaderPtr used  | 
4057  |  |  * @schema:  a precompiled RelaxNG schema  | 
4058  |  |  *  | 
4059  |  |  * Use RelaxNG to validate the document as it is processed.  | 
4060  |  |  * Activation is only possible before the first Read().  | 
4061  |  |  * if @schema is NULL, then RelaxNG validation is deactivated.  | 
4062  |  |  @ The @schema should not be freed until the reader is deallocated  | 
4063  |  |  * or its use has been deactivated.  | 
4064  |  |  *  | 
4065  |  |  * Returns 0 in case the RelaxNG validation could be (de)activated and  | 
4066  |  |  *         -1 in case of error.  | 
4067  |  |  */  | 
4068  |  | int  | 
4069  | 0  | xmlTextReaderRelaxNGSetSchema(xmlTextReaderPtr reader, xmlRelaxNGPtr schema) { | 
4070  | 0  |     if (reader == NULL)  | 
4071  | 0  |         return(-1);  | 
4072  | 0  |     if (schema == NULL) { | 
4073  | 0  |         if (reader->rngSchemas != NULL) { | 
4074  | 0  |       xmlRelaxNGFree(reader->rngSchemas);  | 
4075  | 0  |       reader->rngSchemas = NULL;  | 
4076  | 0  |   }  | 
4077  | 0  |         if (reader->rngValidCtxt != NULL) { | 
4078  | 0  |       if (! reader->rngPreserveCtxt)  | 
4079  | 0  |     xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);  | 
4080  | 0  |       reader->rngValidCtxt = NULL;  | 
4081  | 0  |         }  | 
4082  | 0  |   reader->rngPreserveCtxt = 0;  | 
4083  | 0  |   return(0);  | 
4084  | 0  |     }  | 
4085  | 0  |     if (reader->mode != XML_TEXTREADER_MODE_INITIAL)  | 
4086  | 0  |   return(-1);  | 
4087  | 0  |     if (reader->rngSchemas != NULL) { | 
4088  | 0  |   xmlRelaxNGFree(reader->rngSchemas);  | 
4089  | 0  |   reader->rngSchemas = NULL;  | 
4090  | 0  |     }  | 
4091  | 0  |     if (reader->rngValidCtxt != NULL) { | 
4092  | 0  |   if (! reader->rngPreserveCtxt)  | 
4093  | 0  |       xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);  | 
4094  | 0  |   reader->rngValidCtxt = NULL;  | 
4095  | 0  |     }  | 
4096  | 0  |     reader->rngPreserveCtxt = 0;  | 
4097  | 0  |     reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(schema);  | 
4098  | 0  |     if (reader->rngValidCtxt == NULL)  | 
4099  | 0  |         return(-1);  | 
4100  | 0  |     if (reader->errorFunc != NULL) { | 
4101  | 0  |   xmlRelaxNGSetValidErrors(reader->rngValidCtxt,  | 
4102  | 0  |       xmlTextReaderValidityErrorRelay,  | 
4103  | 0  |       xmlTextReaderValidityWarningRelay,  | 
4104  | 0  |       reader);  | 
4105  | 0  |     }  | 
4106  | 0  |   if (reader->sErrorFunc != NULL) { | 
4107  | 0  |     xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,  | 
4108  | 0  |       xmlTextReaderValidityStructuredRelay,  | 
4109  | 0  |       reader);  | 
4110  | 0  |     }  | 
4111  | 0  |     reader->rngValidErrors = 0;  | 
4112  | 0  |     reader->rngFullNode = NULL;  | 
4113  | 0  |     reader->validate = XML_TEXTREADER_VALIDATE_RNG;  | 
4114  | 0  |     return(0);  | 
4115  | 0  | }  | 
4116  |  |  | 
4117  |  | /**  | 
4118  |  |  * xmlTextReaderLocator:  | 
4119  |  |  * @ctx: the xmlTextReaderPtr used  | 
4120  |  |  * @file: returned file information  | 
4121  |  |  * @line: returned line information  | 
4122  |  |  *  | 
4123  |  |  * Internal locator function for the readers  | 
4124  |  |  *  | 
4125  |  |  * Returns 0 in case the Schema validation could be (de)activated and  | 
4126  |  |  *         -1 in case of error.  | 
4127  |  |  */  | 
4128  |  | static int  | 
4129  | 0  | xmlTextReaderLocator(void *ctx, const char **file, unsigned long *line) { | 
4130  | 0  |     xmlTextReaderPtr reader;  | 
4131  |  | 
  | 
4132  | 0  |     if ((ctx == NULL) || ((file == NULL) && (line == NULL)))  | 
4133  | 0  |         return(-1);  | 
4134  |  |  | 
4135  | 0  |     if (file != NULL)  | 
4136  | 0  |         *file = NULL;  | 
4137  | 0  |     if (line != NULL)  | 
4138  | 0  |         *line = 0;  | 
4139  |  | 
  | 
4140  | 0  |     reader = (xmlTextReaderPtr) ctx;  | 
4141  | 0  |     if ((reader->ctxt != NULL) && (reader->ctxt->input != NULL)) { | 
4142  | 0  |   if (file != NULL)  | 
4143  | 0  |       *file = reader->ctxt->input->filename;  | 
4144  | 0  |   if (line != NULL)  | 
4145  | 0  |       *line = reader->ctxt->input->line;  | 
4146  | 0  |   return(0);  | 
4147  | 0  |     }  | 
4148  | 0  |     if (reader->node != NULL) { | 
4149  | 0  |         long res;  | 
4150  | 0  |   int ret = 0;  | 
4151  |  | 
  | 
4152  | 0  |   if (line != NULL) { | 
4153  | 0  |       res = xmlGetLineNo(reader->node);  | 
4154  | 0  |       if (res > 0)  | 
4155  | 0  |           *line = (unsigned long) res;  | 
4156  | 0  |       else  | 
4157  | 0  |                 ret = -1;  | 
4158  | 0  |   }  | 
4159  | 0  |         if (file != NULL) { | 
4160  | 0  |       xmlDocPtr doc = reader->node->doc;  | 
4161  | 0  |       if ((doc != NULL) && (doc->URL != NULL))  | 
4162  | 0  |           *file = (const char *) doc->URL;  | 
4163  | 0  |       else  | 
4164  | 0  |                 ret = -1;  | 
4165  | 0  |   }  | 
4166  | 0  |   return(ret);  | 
4167  | 0  |     }  | 
4168  | 0  |     return(-1);  | 
4169  | 0  | }  | 
4170  |  |  | 
4171  |  | /**  | 
4172  |  |  * xmlTextReaderSetSchema:  | 
4173  |  |  * @reader:  the xmlTextReaderPtr used  | 
4174  |  |  * @schema:  a precompiled Schema schema  | 
4175  |  |  *  | 
4176  |  |  * Use XSD Schema to validate the document as it is processed.  | 
4177  |  |  * Activation is only possible before the first Read().  | 
4178  |  |  * if @schema is NULL, then Schema validation is deactivated.  | 
4179  |  |  * The @schema should not be freed until the reader is deallocated  | 
4180  |  |  * or its use has been deactivated.  | 
4181  |  |  *  | 
4182  |  |  * Returns 0 in case the Schema validation could be (de)activated and  | 
4183  |  |  *         -1 in case of error.  | 
4184  |  |  */  | 
4185  |  | int  | 
4186  | 0  | xmlTextReaderSetSchema(xmlTextReaderPtr reader, xmlSchemaPtr schema) { | 
4187  | 0  |     if (reader == NULL)  | 
4188  | 0  |         return(-1);  | 
4189  | 0  |     if (schema == NULL) { | 
4190  | 0  |   if (reader->xsdPlug != NULL) { | 
4191  | 0  |       xmlSchemaSAXUnplug(reader->xsdPlug);  | 
4192  | 0  |       reader->xsdPlug = NULL;  | 
4193  | 0  |   }  | 
4194  | 0  |         if (reader->xsdValidCtxt != NULL) { | 
4195  | 0  |       if (! reader->xsdPreserveCtxt)  | 
4196  | 0  |     xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);  | 
4197  | 0  |       reader->xsdValidCtxt = NULL;  | 
4198  | 0  |         }  | 
4199  | 0  |   reader->xsdPreserveCtxt = 0;  | 
4200  | 0  |         if (reader->xsdSchemas != NULL) { | 
4201  | 0  |       xmlSchemaFree(reader->xsdSchemas);  | 
4202  | 0  |       reader->xsdSchemas = NULL;  | 
4203  | 0  |   }  | 
4204  | 0  |   return(0);  | 
4205  | 0  |     }  | 
4206  | 0  |     if (reader->mode != XML_TEXTREADER_MODE_INITIAL)  | 
4207  | 0  |   return(-1);  | 
4208  | 0  |     if (reader->xsdPlug != NULL) { | 
4209  | 0  |   xmlSchemaSAXUnplug(reader->xsdPlug);  | 
4210  | 0  |   reader->xsdPlug = NULL;  | 
4211  | 0  |     }  | 
4212  | 0  |     if (reader->xsdValidCtxt != NULL) { | 
4213  | 0  |   if (! reader->xsdPreserveCtxt)  | 
4214  | 0  |       xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);  | 
4215  | 0  |   reader->xsdValidCtxt = NULL;  | 
4216  | 0  |     }  | 
4217  | 0  |     reader->xsdPreserveCtxt = 0;  | 
4218  | 0  |     if (reader->xsdSchemas != NULL) { | 
4219  | 0  |   xmlSchemaFree(reader->xsdSchemas);  | 
4220  | 0  |   reader->xsdSchemas = NULL;  | 
4221  | 0  |     }  | 
4222  | 0  |     reader->xsdValidCtxt = xmlSchemaNewValidCtxt(schema);  | 
4223  | 0  |     if (reader->xsdValidCtxt == NULL) { | 
4224  | 0  |   xmlSchemaFree(reader->xsdSchemas);  | 
4225  | 0  |   reader->xsdSchemas = NULL;  | 
4226  | 0  |         return(-1);  | 
4227  | 0  |     }  | 
4228  | 0  |     reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,  | 
4229  | 0  |                                        &(reader->ctxt->sax),  | 
4230  | 0  |                &(reader->ctxt->userData));  | 
4231  | 0  |     if (reader->xsdPlug == NULL) { | 
4232  | 0  |   xmlSchemaFree(reader->xsdSchemas);  | 
4233  | 0  |   reader->xsdSchemas = NULL;  | 
4234  | 0  |   xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);  | 
4235  | 0  |   reader->xsdValidCtxt = NULL;  | 
4236  | 0  |   return(-1);  | 
4237  | 0  |     }  | 
4238  | 0  |     xmlSchemaValidateSetLocator(reader->xsdValidCtxt,  | 
4239  | 0  |                                 xmlTextReaderLocator,  | 
4240  | 0  |         (void *) reader);  | 
4241  |  | 
  | 
4242  | 0  |     if (reader->errorFunc != NULL) { | 
4243  | 0  |   xmlSchemaSetValidErrors(reader->xsdValidCtxt,  | 
4244  | 0  |       xmlTextReaderValidityErrorRelay,  | 
4245  | 0  |       xmlTextReaderValidityWarningRelay,  | 
4246  | 0  |       reader);  | 
4247  | 0  |     }  | 
4248  | 0  |   if (reader->sErrorFunc != NULL) { | 
4249  | 0  |     xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,  | 
4250  | 0  |       xmlTextReaderValidityStructuredRelay,  | 
4251  | 0  |       reader);  | 
4252  | 0  |     }  | 
4253  | 0  |     reader->xsdValidErrors = 0;  | 
4254  | 0  |     reader->validate = XML_TEXTREADER_VALIDATE_XSD;  | 
4255  | 0  |     return(0);  | 
4256  | 0  | }  | 
4257  |  |  | 
4258  |  | /**  | 
4259  |  |  * xmlTextReaderRelaxNGValidateInternal:  | 
4260  |  |  * @reader:  the xmlTextReaderPtr used  | 
4261  |  |  * @rng:  the path to a RelaxNG schema or NULL  | 
4262  |  |  * @ctxt: the RelaxNG schema validation context or NULL  | 
4263  |  |  * @options: options (not yet used)  | 
4264  |  |  *  | 
4265  |  |  * Use RelaxNG to validate the document as it is processed.  | 
4266  |  |  * Activation is only possible before the first Read().  | 
4267  |  |  * If both @rng and @ctxt are NULL, then RelaxNG validation is deactivated.  | 
4268  |  |  *  | 
4269  |  |  * Returns 0 in case the RelaxNG validation could be (de)activated and  | 
4270  |  |  *     -1 in case of error.  | 
4271  |  |  */  | 
4272  |  | static int  | 
4273  |  | xmlTextReaderRelaxNGValidateInternal(xmlTextReaderPtr reader,  | 
4274  |  |              const char *rng,  | 
4275  |  |              xmlRelaxNGValidCtxtPtr ctxt,  | 
4276  |  |              int options ATTRIBUTE_UNUSED)  | 
4277  | 0  | { | 
4278  | 0  |     if (reader == NULL)  | 
4279  | 0  |   return(-1);  | 
4280  |  |  | 
4281  | 0  |     if ((rng != NULL) && (ctxt != NULL))  | 
4282  | 0  |   return (-1);  | 
4283  |  |  | 
4284  | 0  |     if (((rng != NULL) || (ctxt != NULL)) &&  | 
4285  | 0  |   ((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||  | 
4286  | 0  |    (reader->ctxt == NULL)))  | 
4287  | 0  |   return(-1);  | 
4288  |  |  | 
4289  |  |     /* Cleanup previous validation stuff. */  | 
4290  | 0  |     if (reader->rngValidCtxt != NULL) { | 
4291  | 0  |   if ( !reader->rngPreserveCtxt)  | 
4292  | 0  |       xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);  | 
4293  | 0  |   reader->rngValidCtxt = NULL;  | 
4294  | 0  |     }  | 
4295  | 0  |     reader->rngPreserveCtxt = 0;  | 
4296  | 0  |     if (reader->rngSchemas != NULL) { | 
4297  | 0  |   xmlRelaxNGFree(reader->rngSchemas);  | 
4298  | 0  |   reader->rngSchemas = NULL;  | 
4299  | 0  |     }  | 
4300  |  | 
  | 
4301  | 0  |     if ((rng == NULL) && (ctxt == NULL)) { | 
4302  |  |   /* We just want to deactivate the validation, so get out. */  | 
4303  | 0  |   return(0);  | 
4304  | 0  |     }  | 
4305  |  |  | 
4306  |  |  | 
4307  | 0  |     if (rng != NULL) { | 
4308  | 0  |   xmlRelaxNGParserCtxtPtr pctxt;  | 
4309  |  |   /* Parse the schema and create validation environment. */  | 
4310  |  | 
  | 
4311  | 0  |   pctxt = xmlRelaxNGNewParserCtxt(rng);  | 
4312  | 0  |   if (reader->errorFunc != NULL) { | 
4313  | 0  |       xmlRelaxNGSetParserErrors(pctxt,  | 
4314  | 0  |     xmlTextReaderValidityErrorRelay,  | 
4315  | 0  |     xmlTextReaderValidityWarningRelay,  | 
4316  | 0  |     reader);  | 
4317  | 0  |   }  | 
4318  | 0  |   if (reader->sErrorFunc != NULL) { | 
4319  | 0  |       xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,  | 
4320  | 0  |     xmlTextReaderValidityStructuredRelay,  | 
4321  | 0  |     reader);  | 
4322  | 0  |   }  | 
4323  | 0  |   reader->rngSchemas = xmlRelaxNGParse(pctxt);  | 
4324  | 0  |   xmlRelaxNGFreeParserCtxt(pctxt);  | 
4325  | 0  |   if (reader->rngSchemas == NULL)  | 
4326  | 0  |       return(-1);  | 
4327  | 0  |   reader->rngValidCtxt = xmlRelaxNGNewValidCtxt(reader->rngSchemas);  | 
4328  | 0  |   if (reader->rngValidCtxt == NULL) { | 
4329  | 0  |       xmlRelaxNGFree(reader->rngSchemas);  | 
4330  | 0  |       reader->rngSchemas = NULL;  | 
4331  | 0  |       return(-1);  | 
4332  | 0  |   }  | 
4333  | 0  |     } else { | 
4334  |  |   /* Use the given validation context. */  | 
4335  | 0  |   reader->rngValidCtxt = ctxt;  | 
4336  | 0  |   reader->rngPreserveCtxt = 1;  | 
4337  | 0  |     }  | 
4338  |  |     /*  | 
4339  |  |     * Redirect the validation context's error channels to use  | 
4340  |  |     * the reader channels.  | 
4341  |  |     * TODO: In case the user provides the validation context we  | 
4342  |  |     * could make this redirection optional.  | 
4343  |  |     */  | 
4344  | 0  |     if (reader->errorFunc != NULL) { | 
4345  | 0  |   xmlRelaxNGSetValidErrors(reader->rngValidCtxt,  | 
4346  | 0  |        xmlTextReaderValidityErrorRelay,  | 
4347  | 0  |        xmlTextReaderValidityWarningRelay,  | 
4348  | 0  |        reader);  | 
4349  | 0  |     }  | 
4350  | 0  |   if (reader->sErrorFunc != NULL) { | 
4351  | 0  |     xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,  | 
4352  | 0  |       xmlTextReaderValidityStructuredRelay,  | 
4353  | 0  |       reader);  | 
4354  | 0  |     }  | 
4355  | 0  |     reader->rngValidErrors = 0;  | 
4356  | 0  |     reader->rngFullNode = NULL;  | 
4357  | 0  |     reader->validate = XML_TEXTREADER_VALIDATE_RNG;  | 
4358  | 0  |     return(0);  | 
4359  | 0  | }  | 
4360  |  |  | 
4361  |  | /**  | 
4362  |  |  * xmlTextReaderSchemaValidateInternal:  | 
4363  |  |  * @reader:  the xmlTextReaderPtr used  | 
4364  |  |  * @xsd:  the path to a W3C XSD schema or NULL  | 
4365  |  |  * @ctxt: the XML Schema validation context or NULL  | 
4366  |  |  * @options: options (not used yet)  | 
4367  |  |  *  | 
4368  |  |  * Validate the document as it is processed using XML Schema.  | 
4369  |  |  * Activation is only possible before the first Read().  | 
4370  |  |  * If both @xsd and @ctxt are NULL then XML Schema validation is deactivated.  | 
4371  |  |  *  | 
4372  |  |  * Returns 0 in case the schemas validation could be (de)activated and  | 
4373  |  |  *         -1 in case of error.  | 
4374  |  |  */  | 
4375  |  | static int  | 
4376  |  | xmlTextReaderSchemaValidateInternal(xmlTextReaderPtr reader,  | 
4377  |  |             const char *xsd,  | 
4378  |  |             xmlSchemaValidCtxtPtr ctxt,  | 
4379  |  |             int options ATTRIBUTE_UNUSED)  | 
4380  | 0  | { | 
4381  | 0  |     if (reader == NULL)  | 
4382  | 0  |         return(-1);  | 
4383  |  |  | 
4384  | 0  |     if ((xsd != NULL) && (ctxt != NULL))  | 
4385  | 0  |   return(-1);  | 
4386  |  |  | 
4387  | 0  |     if (((xsd != NULL) || (ctxt != NULL)) &&  | 
4388  | 0  |   ((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||  | 
4389  | 0  |         (reader->ctxt == NULL)))  | 
4390  | 0  |   return(-1);  | 
4391  |  |  | 
4392  |  |     /* Cleanup previous validation stuff. */  | 
4393  | 0  |     if (reader->xsdPlug != NULL) { | 
4394  | 0  |   xmlSchemaSAXUnplug(reader->xsdPlug);  | 
4395  | 0  |   reader->xsdPlug = NULL;  | 
4396  | 0  |     }  | 
4397  | 0  |     if (reader->xsdValidCtxt != NULL) { | 
4398  | 0  |   if (! reader->xsdPreserveCtxt)  | 
4399  | 0  |       xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);  | 
4400  | 0  |   reader->xsdValidCtxt = NULL;  | 
4401  | 0  |     }  | 
4402  | 0  |     reader->xsdPreserveCtxt = 0;  | 
4403  | 0  |     if (reader->xsdSchemas != NULL) { | 
4404  | 0  |   xmlSchemaFree(reader->xsdSchemas);  | 
4405  | 0  |   reader->xsdSchemas = NULL;  | 
4406  | 0  |     }  | 
4407  |  | 
  | 
4408  | 0  |     if ((xsd == NULL) && (ctxt == NULL)) { | 
4409  |  |   /* We just want to deactivate the validation, so get out. */  | 
4410  | 0  |   return(0);  | 
4411  | 0  |     }  | 
4412  |  |  | 
4413  | 0  |     if (xsd != NULL) { | 
4414  | 0  |   xmlSchemaParserCtxtPtr pctxt;  | 
4415  |  |   /* Parse the schema and create validation environment. */  | 
4416  | 0  |   pctxt = xmlSchemaNewParserCtxt(xsd);  | 
4417  | 0  |   if (reader->errorFunc != NULL) { | 
4418  | 0  |       xmlSchemaSetParserErrors(pctxt,  | 
4419  | 0  |     xmlTextReaderValidityErrorRelay,  | 
4420  | 0  |     xmlTextReaderValidityWarningRelay,  | 
4421  | 0  |     reader);  | 
4422  | 0  |   }  | 
4423  | 0  |   reader->xsdSchemas = xmlSchemaParse(pctxt);  | 
4424  | 0  |   xmlSchemaFreeParserCtxt(pctxt);  | 
4425  | 0  |   if (reader->xsdSchemas == NULL)  | 
4426  | 0  |       return(-1);  | 
4427  | 0  |   reader->xsdValidCtxt = xmlSchemaNewValidCtxt(reader->xsdSchemas);  | 
4428  | 0  |   if (reader->xsdValidCtxt == NULL) { | 
4429  | 0  |       xmlSchemaFree(reader->xsdSchemas);  | 
4430  | 0  |       reader->xsdSchemas = NULL;  | 
4431  | 0  |       return(-1);  | 
4432  | 0  |   }  | 
4433  | 0  |   reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,  | 
4434  | 0  |       &(reader->ctxt->sax),  | 
4435  | 0  |       &(reader->ctxt->userData));  | 
4436  | 0  |   if (reader->xsdPlug == NULL) { | 
4437  | 0  |       xmlSchemaFree(reader->xsdSchemas);  | 
4438  | 0  |       reader->xsdSchemas = NULL;  | 
4439  | 0  |       xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);  | 
4440  | 0  |       reader->xsdValidCtxt = NULL;  | 
4441  | 0  |       return(-1);  | 
4442  | 0  |   }  | 
4443  | 0  |     } else { | 
4444  |  |   /* Use the given validation context. */  | 
4445  | 0  |   reader->xsdValidCtxt = ctxt;  | 
4446  | 0  |   reader->xsdPreserveCtxt = 1;  | 
4447  | 0  |   reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,  | 
4448  | 0  |       &(reader->ctxt->sax),  | 
4449  | 0  |       &(reader->ctxt->userData));  | 
4450  | 0  |   if (reader->xsdPlug == NULL) { | 
4451  | 0  |       reader->xsdValidCtxt = NULL;  | 
4452  | 0  |       reader->xsdPreserveCtxt = 0;  | 
4453  | 0  |       return(-1);  | 
4454  | 0  |   }  | 
4455  | 0  |     }  | 
4456  | 0  |     xmlSchemaValidateSetLocator(reader->xsdValidCtxt,  | 
4457  | 0  |                                 xmlTextReaderLocator,  | 
4458  | 0  |         (void *) reader);  | 
4459  |  |     /*  | 
4460  |  |     * Redirect the validation context's error channels to use  | 
4461  |  |     * the reader channels.  | 
4462  |  |     * TODO: In case the user provides the validation context we  | 
4463  |  |     *   could make this redirection optional.  | 
4464  |  |     */  | 
4465  | 0  |     if (reader->errorFunc != NULL) { | 
4466  | 0  |   xmlSchemaSetValidErrors(reader->xsdValidCtxt,  | 
4467  | 0  |        xmlTextReaderValidityErrorRelay,  | 
4468  | 0  |        xmlTextReaderValidityWarningRelay,  | 
4469  | 0  |        reader);  | 
4470  | 0  |     }  | 
4471  | 0  |   if (reader->sErrorFunc != NULL) { | 
4472  | 0  |     xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,  | 
4473  | 0  |       xmlTextReaderValidityStructuredRelay,  | 
4474  | 0  |       reader);  | 
4475  | 0  |     }  | 
4476  | 0  |     reader->xsdValidErrors = 0;  | 
4477  | 0  |     reader->validate = XML_TEXTREADER_VALIDATE_XSD;  | 
4478  | 0  |     return(0);  | 
4479  | 0  | }  | 
4480  |  |  | 
4481  |  | /**  | 
4482  |  |  * xmlTextReaderSchemaValidateCtxt:  | 
4483  |  |  * @reader:  the xmlTextReaderPtr used  | 
4484  |  |  * @ctxt: the XML Schema validation context or NULL  | 
4485  |  |  * @options: options (not used yet)  | 
4486  |  |  *  | 
4487  |  |  * Use W3C XSD schema context to validate the document as it is processed.  | 
4488  |  |  * Activation is only possible before the first Read().  | 
4489  |  |  * If @ctxt is NULL, then XML Schema validation is deactivated.  | 
4490  |  |  *  | 
4491  |  |  * Returns 0 in case the schemas validation could be (de)activated and  | 
4492  |  |  *         -1 in case of error.  | 
4493  |  |  */  | 
4494  |  | int  | 
4495  |  | xmlTextReaderSchemaValidateCtxt(xmlTextReaderPtr reader,  | 
4496  |  |             xmlSchemaValidCtxtPtr ctxt,  | 
4497  |  |             int options)  | 
4498  | 0  | { | 
4499  | 0  |     return(xmlTextReaderSchemaValidateInternal(reader, NULL, ctxt, options));  | 
4500  | 0  | }  | 
4501  |  |  | 
4502  |  | /**  | 
4503  |  |  * xmlTextReaderSchemaValidate:  | 
4504  |  |  * @reader:  the xmlTextReaderPtr used  | 
4505  |  |  * @xsd:  the path to a W3C XSD schema or NULL  | 
4506  |  |  *  | 
4507  |  |  * Use W3C XSD schema to validate the document as it is processed.  | 
4508  |  |  * Activation is only possible before the first Read().  | 
4509  |  |  * If @xsd is NULL, then XML Schema validation is deactivated.  | 
4510  |  |  *  | 
4511  |  |  * Returns 0 in case the schemas validation could be (de)activated and  | 
4512  |  |  *         -1 in case of error.  | 
4513  |  |  */  | 
4514  |  | int  | 
4515  |  | xmlTextReaderSchemaValidate(xmlTextReaderPtr reader, const char *xsd)  | 
4516  | 0  | { | 
4517  | 0  |     return(xmlTextReaderSchemaValidateInternal(reader, xsd, NULL, 0));  | 
4518  | 0  | }  | 
4519  |  |  | 
4520  |  | /**  | 
4521  |  |  * xmlTextReaderRelaxNGValidateCtxt:  | 
4522  |  |  * @reader:  the xmlTextReaderPtr used  | 
4523  |  |  * @ctxt: the RelaxNG schema validation context or NULL  | 
4524  |  |  * @options: options (not used yet)  | 
4525  |  |  *  | 
4526  |  |  * Use RelaxNG schema context to validate the document as it is processed.  | 
4527  |  |  * Activation is only possible before the first Read().  | 
4528  |  |  * If @ctxt is NULL, then RelaxNG schema validation is deactivated.  | 
4529  |  |  *  | 
4530  |  |  * Returns 0 in case the schemas validation could be (de)activated and  | 
4531  |  |  *         -1 in case of error.  | 
4532  |  |  */  | 
4533  |  | int  | 
4534  |  | xmlTextReaderRelaxNGValidateCtxt(xmlTextReaderPtr reader,  | 
4535  |  |          xmlRelaxNGValidCtxtPtr ctxt,  | 
4536  |  |          int options)  | 
4537  | 0  | { | 
4538  | 0  |     return(xmlTextReaderRelaxNGValidateInternal(reader, NULL, ctxt, options));  | 
4539  | 0  | }  | 
4540  |  |  | 
4541  |  | /**  | 
4542  |  |  * xmlTextReaderRelaxNGValidate:  | 
4543  |  |  * @reader:  the xmlTextReaderPtr used  | 
4544  |  |  * @rng:  the path to a RelaxNG schema or NULL  | 
4545  |  |  *  | 
4546  |  |  * Use RelaxNG schema to validate the document as it is processed.  | 
4547  |  |  * Activation is only possible before the first Read().  | 
4548  |  |  * If @rng is NULL, then RelaxNG schema validation is deactivated.  | 
4549  |  |  *  | 
4550  |  |  * Returns 0 in case the schemas validation could be (de)activated and  | 
4551  |  |  *         -1 in case of error.  | 
4552  |  |  */  | 
4553  |  | int  | 
4554  |  | xmlTextReaderRelaxNGValidate(xmlTextReaderPtr reader, const char *rng)  | 
4555  | 0  | { | 
4556  | 0  |     return(xmlTextReaderRelaxNGValidateInternal(reader, rng, NULL, 0));  | 
4557  | 0  | }  | 
4558  |  |  | 
4559  |  | #endif  | 
4560  |  |  | 
4561  |  | /**  | 
4562  |  |  * xmlTextReaderIsNamespaceDecl:  | 
4563  |  |  * @reader: the xmlTextReaderPtr used  | 
4564  |  |  *  | 
4565  |  |  * Determine whether the current node is a namespace declaration  | 
4566  |  |  * rather than a regular attribute.  | 
4567  |  |  *  | 
4568  |  |  * Returns 1 if the current node is a namespace declaration, 0 if it  | 
4569  |  |  * is a regular attribute or other type of node, or -1 in case of  | 
4570  |  |  * error.  | 
4571  |  |  */  | 
4572  |  | int  | 
4573  | 0  | xmlTextReaderIsNamespaceDecl(xmlTextReaderPtr reader) { | 
4574  | 0  |     xmlNodePtr node;  | 
4575  | 0  |     if (reader == NULL)  | 
4576  | 0  |   return(-1);  | 
4577  | 0  |     if (reader->node == NULL)  | 
4578  | 0  |   return(-1);  | 
4579  | 0  |     if (reader->curnode != NULL)  | 
4580  | 0  |   node = reader->curnode;  | 
4581  | 0  |     else  | 
4582  | 0  |   node = reader->node;  | 
4583  |  | 
  | 
4584  | 0  |     if (XML_NAMESPACE_DECL == node->type)  | 
4585  | 0  |   return(1);  | 
4586  | 0  |     else  | 
4587  | 0  |   return(0);  | 
4588  | 0  | }  | 
4589  |  |  | 
4590  |  | /**  | 
4591  |  |  * xmlTextReaderConstXmlVersion:  | 
4592  |  |  * @reader:  the xmlTextReaderPtr used  | 
4593  |  |  *  | 
4594  |  |  * Determine the XML version of the document being read.  | 
4595  |  |  *  | 
4596  |  |  * Returns a string containing the XML version of the document or NULL  | 
4597  |  |  * in case of error.  The string is deallocated with the reader.  | 
4598  |  |  */  | 
4599  |  | const xmlChar *  | 
4600  | 0  | xmlTextReaderConstXmlVersion(xmlTextReaderPtr reader) { | 
4601  | 0  |     xmlDocPtr doc = NULL;  | 
4602  | 0  |     if (reader == NULL)  | 
4603  | 0  |   return(NULL);  | 
4604  | 0  |     if (reader->doc != NULL)  | 
4605  | 0  |         doc = reader->doc;  | 
4606  | 0  |     else if (reader->ctxt != NULL)  | 
4607  | 0  |   doc = reader->ctxt->myDoc;  | 
4608  | 0  |     if (doc == NULL)  | 
4609  | 0  |   return(NULL);  | 
4610  |  |  | 
4611  | 0  |     if (doc->version == NULL)  | 
4612  | 0  |   return(NULL);  | 
4613  | 0  |     else  | 
4614  | 0  |       return(CONSTSTR(doc->version));  | 
4615  | 0  | }  | 
4616  |  |  | 
4617  |  | /**  | 
4618  |  |  * xmlTextReaderStandalone:  | 
4619  |  |  * @reader:  the xmlTextReaderPtr used  | 
4620  |  |  *  | 
4621  |  |  * Determine the standalone status of the document being read.  | 
4622  |  |  *  | 
4623  |  |  * Returns 1 if the document was declared to be standalone, 0 if it  | 
4624  |  |  * was declared to be not standalone, or -1 if the document did not  | 
4625  |  |  * specify its standalone status or in case of error.  | 
4626  |  |  */  | 
4627  |  | int  | 
4628  | 0  | xmlTextReaderStandalone(xmlTextReaderPtr reader) { | 
4629  | 0  |     xmlDocPtr doc = NULL;  | 
4630  | 0  |     if (reader == NULL)  | 
4631  | 0  |   return(-1);  | 
4632  | 0  |     if (reader->doc != NULL)  | 
4633  | 0  |         doc = reader->doc;  | 
4634  | 0  |     else if (reader->ctxt != NULL)  | 
4635  | 0  |   doc = reader->ctxt->myDoc;  | 
4636  | 0  |     if (doc == NULL)  | 
4637  | 0  |   return(-1);  | 
4638  |  |  | 
4639  | 0  |     return(doc->standalone);  | 
4640  | 0  | }  | 
4641  |  |  | 
4642  |  | /************************************************************************  | 
4643  |  |  *                  *  | 
4644  |  |  *      Error Handling Extensions                       *  | 
4645  |  |  *                  *  | 
4646  |  |  ************************************************************************/  | 
4647  |  |  | 
4648  |  | /* helper to build a xmlMalloc'ed string from a format and va_list */  | 
4649  |  | static char *  | 
4650  | 0  | xmlTextReaderBuildMessage(const char *msg, va_list ap) { | 
4651  | 0  |     int size = 0;  | 
4652  | 0  |     int chars;  | 
4653  | 0  |     char *larger;  | 
4654  | 0  |     char *str = NULL;  | 
4655  | 0  |     va_list aq;  | 
4656  |  | 
  | 
4657  | 0  |     while (1) { | 
4658  | 0  |         VA_COPY(aq, ap);  | 
4659  | 0  |         chars = vsnprintf(str, size, msg, aq);  | 
4660  | 0  |         va_end(aq);  | 
4661  | 0  |         if (chars < 0) { | 
4662  | 0  |       xmlGenericError(xmlGenericErrorContext, "vsnprintf failed !\n");  | 
4663  | 0  |       if (str)  | 
4664  | 0  |     xmlFree(str);  | 
4665  | 0  |       return NULL;  | 
4666  | 0  |   }  | 
4667  | 0  |   if ((chars < size) || (size == MAX_ERR_MSG_SIZE))  | 
4668  | 0  |             break;  | 
4669  | 0  |         if (chars < MAX_ERR_MSG_SIZE)  | 
4670  | 0  |   size = chars + 1;  | 
4671  | 0  |   else  | 
4672  | 0  |     size = MAX_ERR_MSG_SIZE;  | 
4673  | 0  |         if ((larger = (char *) xmlRealloc(str, size)) == NULL) { | 
4674  | 0  |       xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");  | 
4675  | 0  |       if (str)  | 
4676  | 0  |                 xmlFree(str);  | 
4677  | 0  |             return NULL;  | 
4678  | 0  |         }  | 
4679  | 0  |         str = larger;  | 
4680  | 0  |     }  | 
4681  |  |  | 
4682  | 0  |     return str;  | 
4683  | 0  | }  | 
4684  |  |  | 
4685  |  | /**  | 
4686  |  |  * xmlTextReaderLocatorLineNumber:  | 
4687  |  |  * @locator: the xmlTextReaderLocatorPtr used  | 
4688  |  |  *  | 
4689  |  |  * Obtain the line number for the given locator.  | 
4690  |  |  *  | 
4691  |  |  * Returns the line number or -1 in case of error.  | 
4692  |  |  */  | 
4693  |  | int  | 
4694  | 0  | xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator) { | 
4695  |  |     /* we know that locator is a xmlParserCtxtPtr */  | 
4696  | 0  |     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;  | 
4697  | 0  |     int ret = -1;  | 
4698  |  | 
  | 
4699  | 0  |     if (locator == NULL)  | 
4700  | 0  |         return(-1);  | 
4701  | 0  |     if (ctx->node != NULL) { | 
4702  | 0  |   ret = xmlGetLineNo(ctx->node);  | 
4703  | 0  |     }  | 
4704  | 0  |     else { | 
4705  |  |   /* inspired from error.c */  | 
4706  | 0  |   xmlParserInputPtr input;  | 
4707  | 0  |   input = ctx->input;  | 
4708  | 0  |   if ((input->filename == NULL) && (ctx->inputNr > 1))  | 
4709  | 0  |       input = ctx->inputTab[ctx->inputNr - 2];  | 
4710  | 0  |   if (input != NULL) { | 
4711  | 0  |       ret = input->line;  | 
4712  | 0  |   }  | 
4713  | 0  |   else { | 
4714  | 0  |       ret = -1;  | 
4715  | 0  |   }  | 
4716  | 0  |     }  | 
4717  |  | 
  | 
4718  | 0  |     return ret;  | 
4719  | 0  | }  | 
4720  |  |  | 
4721  |  | /**  | 
4722  |  |  * xmlTextReaderLocatorBaseURI:  | 
4723  |  |  * @locator: the xmlTextReaderLocatorPtr used  | 
4724  |  |  *  | 
4725  |  |  * Obtain the base URI for the given locator.  | 
4726  |  |  *  | 
4727  |  |  * Returns the base URI or NULL in case of error,  | 
4728  |  |  *    if non NULL it need to be freed by the caller.  | 
4729  |  |  */  | 
4730  |  | xmlChar *  | 
4731  | 0  | xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator) { | 
4732  |  |     /* we know that locator is a xmlParserCtxtPtr */  | 
4733  | 0  |     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;  | 
4734  | 0  |     xmlChar *ret = NULL;  | 
4735  |  | 
  | 
4736  | 0  |     if (locator == NULL)  | 
4737  | 0  |         return(NULL);  | 
4738  | 0  |     if (ctx->node != NULL) { | 
4739  | 0  |   ret = xmlNodeGetBase(NULL,ctx->node);  | 
4740  | 0  |     }  | 
4741  | 0  |     else { | 
4742  |  |   /* inspired from error.c */  | 
4743  | 0  |   xmlParserInputPtr input;  | 
4744  | 0  |   input = ctx->input;  | 
4745  | 0  |   if ((input->filename == NULL) && (ctx->inputNr > 1))  | 
4746  | 0  |       input = ctx->inputTab[ctx->inputNr - 2];  | 
4747  | 0  |   if (input != NULL) { | 
4748  | 0  |       ret = xmlStrdup(BAD_CAST input->filename);  | 
4749  | 0  |   }  | 
4750  | 0  |   else { | 
4751  | 0  |       ret = NULL;  | 
4752  | 0  |   }  | 
4753  | 0  |     }  | 
4754  |  | 
  | 
4755  | 0  |     return ret;  | 
4756  | 0  | }  | 
4757  |  |  | 
4758  |  | static void  | 
4759  |  | xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity,  | 
4760  |  |                           char *str)  | 
4761  | 0  | { | 
4762  | 0  |     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;  | 
4763  |  | 
  | 
4764  | 0  |     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;  | 
4765  |  | 
  | 
4766  | 0  |     if (str != NULL) { | 
4767  | 0  |         if (reader->errorFunc)  | 
4768  | 0  |             reader->errorFunc(reader->errorFuncArg, str, severity,  | 
4769  | 0  |                               (xmlTextReaderLocatorPtr) ctx);  | 
4770  | 0  |         xmlFree(str);  | 
4771  | 0  |     }  | 
4772  | 0  | }  | 
4773  |  |  | 
4774  |  | static void  | 
4775  |  | xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error)  | 
4776  | 0  | { | 
4777  | 0  |     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;  | 
4778  |  | 
  | 
4779  | 0  |     xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;  | 
4780  |  | 
  | 
4781  | 0  |     if (error && reader->sErrorFunc) { | 
4782  | 0  |         reader->sErrorFunc(reader->errorFuncArg, (xmlErrorPtr) error);  | 
4783  | 0  |     }  | 
4784  | 0  | }  | 
4785  |  |  | 
4786  |  | static void LIBXML_ATTR_FORMAT(2,3)  | 
4787  |  | xmlTextReaderError(void *ctxt, const char *msg, ...)  | 
4788  | 0  | { | 
4789  | 0  |     va_list ap;  | 
4790  |  | 
  | 
4791  | 0  |     va_start(ap, msg);  | 
4792  | 0  |     xmlTextReaderGenericError(ctxt,  | 
4793  | 0  |                               XML_PARSER_SEVERITY_ERROR,  | 
4794  | 0  |                               xmlTextReaderBuildMessage(msg, ap));  | 
4795  | 0  |     va_end(ap);  | 
4796  |  | 
  | 
4797  | 0  | }  | 
4798  |  |  | 
4799  |  | static void LIBXML_ATTR_FORMAT(2,3)  | 
4800  |  | xmlTextReaderWarning(void *ctxt, const char *msg, ...)  | 
4801  | 0  | { | 
4802  | 0  |     va_list ap;  | 
4803  |  | 
  | 
4804  | 0  |     va_start(ap, msg);  | 
4805  | 0  |     xmlTextReaderGenericError(ctxt,  | 
4806  | 0  |                               XML_PARSER_SEVERITY_WARNING,  | 
4807  | 0  |                               xmlTextReaderBuildMessage(msg, ap));  | 
4808  | 0  |     va_end(ap);  | 
4809  | 0  | }  | 
4810  |  |  | 
4811  |  | static void  | 
4812  |  | xmlTextReaderValidityError(void *ctxt, const char *msg, ...)  | 
4813  | 0  | { | 
4814  | 0  |     va_list ap;  | 
4815  |  | 
  | 
4816  | 0  |     int len = xmlStrlen((const xmlChar *) msg);  | 
4817  |  | 
  | 
4818  | 0  |     if ((len > 1) && (msg[len - 2] != ':')) { | 
4819  |  |         /*  | 
4820  |  |          * some callbacks only report locator information:  | 
4821  |  |          * skip them (mimicking behaviour in error.c)  | 
4822  |  |          */  | 
4823  | 0  |         va_start(ap, msg);  | 
4824  | 0  |         xmlTextReaderGenericError(ctxt,  | 
4825  | 0  |                                   XML_PARSER_SEVERITY_VALIDITY_ERROR,  | 
4826  | 0  |                                   xmlTextReaderBuildMessage(msg, ap));  | 
4827  | 0  |         va_end(ap);  | 
4828  | 0  |     }  | 
4829  | 0  | }  | 
4830  |  |  | 
4831  |  | static void  | 
4832  |  | xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...)  | 
4833  | 0  | { | 
4834  | 0  |     va_list ap;  | 
4835  |  | 
  | 
4836  | 0  |     int len = xmlStrlen((const xmlChar *) msg);  | 
4837  |  | 
  | 
4838  | 0  |     if ((len != 0) && (msg[len - 1] != ':')) { | 
4839  |  |         /*  | 
4840  |  |          * some callbacks only report locator information:  | 
4841  |  |          * skip them (mimicking behaviour in error.c)  | 
4842  |  |          */  | 
4843  | 0  |         va_start(ap, msg);  | 
4844  | 0  |         xmlTextReaderGenericError(ctxt,  | 
4845  | 0  |                                   XML_PARSER_SEVERITY_VALIDITY_WARNING,  | 
4846  | 0  |                                   xmlTextReaderBuildMessage(msg, ap));  | 
4847  | 0  |         va_end(ap);  | 
4848  | 0  |     }  | 
4849  | 0  | }  | 
4850  |  |  | 
4851  |  | /**  | 
4852  |  |  * xmlTextReaderSetErrorHandler:  | 
4853  |  |  * @reader:  the xmlTextReaderPtr used  | 
4854  |  |  * @f:  the callback function to call on error and warnings  | 
4855  |  |  * @arg:    a user argument to pass to the callback function  | 
4856  |  |  *  | 
4857  |  |  * Register a callback function that will be called on error and warnings.  | 
4858  |  |  *  | 
4859  |  |  * If @f is NULL, the default error and warning handlers are restored.  | 
4860  |  |  */  | 
4861  |  | void  | 
4862  |  | xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,  | 
4863  |  |                              xmlTextReaderErrorFunc f, void *arg)  | 
4864  | 0  | { | 
4865  | 0  |     if (f != NULL) { | 
4866  | 0  |         reader->ctxt->sax->error = xmlTextReaderError;  | 
4867  | 0  |         reader->ctxt->sax->serror = NULL;  | 
4868  | 0  |         reader->ctxt->vctxt.error = xmlTextReaderValidityError;  | 
4869  | 0  |         reader->ctxt->sax->warning = xmlTextReaderWarning;  | 
4870  | 0  |         reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;  | 
4871  | 0  |         reader->errorFunc = f;  | 
4872  | 0  |         reader->sErrorFunc = NULL;  | 
4873  | 0  |         reader->errorFuncArg = arg;  | 
4874  | 0  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
4875  | 0  |         if (reader->rngValidCtxt) { | 
4876  | 0  |             xmlRelaxNGSetValidErrors(reader->rngValidCtxt,  | 
4877  | 0  |                                      xmlTextReaderValidityErrorRelay,  | 
4878  | 0  |                                      xmlTextReaderValidityWarningRelay,  | 
4879  | 0  |                                      reader);  | 
4880  | 0  |             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,  | 
4881  | 0  |                                                reader);  | 
4882  | 0  |         }  | 
4883  | 0  |         if (reader->xsdValidCtxt) { | 
4884  | 0  |             xmlSchemaSetValidErrors(reader->xsdValidCtxt,  | 
4885  | 0  |                                     xmlTextReaderValidityErrorRelay,  | 
4886  | 0  |                                     xmlTextReaderValidityWarningRelay,  | 
4887  | 0  |                                     reader);  | 
4888  | 0  |             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,  | 
4889  | 0  |                                               reader);  | 
4890  | 0  |         }  | 
4891  | 0  | #endif  | 
4892  | 0  |     } else { | 
4893  |  |         /* restore defaults */  | 
4894  | 0  |         reader->ctxt->sax->error = xmlParserError;  | 
4895  | 0  |         reader->ctxt->vctxt.error = xmlParserValidityError;  | 
4896  | 0  |         reader->ctxt->sax->warning = xmlParserWarning;  | 
4897  | 0  |         reader->ctxt->vctxt.warning = xmlParserValidityWarning;  | 
4898  | 0  |         reader->errorFunc = NULL;  | 
4899  | 0  |         reader->sErrorFunc = NULL;  | 
4900  | 0  |         reader->errorFuncArg = NULL;  | 
4901  | 0  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
4902  | 0  |         if (reader->rngValidCtxt) { | 
4903  | 0  |             xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,  | 
4904  | 0  |                                      reader);  | 
4905  | 0  |             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,  | 
4906  | 0  |                                                reader);  | 
4907  | 0  |         }  | 
4908  | 0  |         if (reader->xsdValidCtxt) { | 
4909  | 0  |             xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,  | 
4910  | 0  |                                     reader);  | 
4911  | 0  |             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,  | 
4912  | 0  |                                               reader);  | 
4913  | 0  |         }  | 
4914  | 0  | #endif  | 
4915  | 0  |     }  | 
4916  | 0  | }  | 
4917  |  |  | 
4918  |  | /**  | 
4919  |  | * xmlTextReaderSetStructuredErrorHandler:  | 
4920  |  |  * @reader:  the xmlTextReaderPtr used  | 
4921  |  |  * @f:  the callback function to call on error and warnings  | 
4922  |  |  * @arg:    a user argument to pass to the callback function  | 
4923  |  |  *  | 
4924  |  |  * Register a callback function that will be called on error and warnings.  | 
4925  |  |  *  | 
4926  |  |  * If @f is NULL, the default error and warning handlers are restored.  | 
4927  |  |  */  | 
4928  |  | void  | 
4929  |  | xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader,  | 
4930  |  |                                        xmlStructuredErrorFunc f, void *arg)  | 
4931  | 0  | { | 
4932  | 0  |     if (f != NULL) { | 
4933  | 0  |         reader->ctxt->sax->error = NULL;  | 
4934  | 0  |         reader->ctxt->sax->serror = xmlTextReaderStructuredError;  | 
4935  | 0  |         reader->ctxt->vctxt.error = xmlTextReaderValidityError;  | 
4936  | 0  |         reader->ctxt->sax->warning = xmlTextReaderWarning;  | 
4937  | 0  |         reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;  | 
4938  | 0  |         reader->sErrorFunc = f;  | 
4939  | 0  |         reader->errorFunc = NULL;  | 
4940  | 0  |         reader->errorFuncArg = arg;  | 
4941  | 0  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
4942  | 0  |         if (reader->rngValidCtxt) { | 
4943  | 0  |             xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,  | 
4944  | 0  |                                      reader);  | 
4945  | 0  |             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,  | 
4946  | 0  |                                         xmlTextReaderValidityStructuredRelay,  | 
4947  | 0  |                                                reader);  | 
4948  | 0  |         }  | 
4949  | 0  |         if (reader->xsdValidCtxt) { | 
4950  | 0  |             xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,  | 
4951  | 0  |                                     reader);  | 
4952  | 0  |             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,  | 
4953  | 0  |                                        xmlTextReaderValidityStructuredRelay,  | 
4954  | 0  |                                               reader);  | 
4955  | 0  |         }  | 
4956  | 0  | #endif  | 
4957  | 0  |     } else { | 
4958  |  |         /* restore defaults */  | 
4959  | 0  |         reader->ctxt->sax->error = xmlParserError;  | 
4960  | 0  |         reader->ctxt->sax->serror = NULL;  | 
4961  | 0  |         reader->ctxt->vctxt.error = xmlParserValidityError;  | 
4962  | 0  |         reader->ctxt->sax->warning = xmlParserWarning;  | 
4963  | 0  |         reader->ctxt->vctxt.warning = xmlParserValidityWarning;  | 
4964  | 0  |         reader->errorFunc = NULL;  | 
4965  | 0  |         reader->sErrorFunc = NULL;  | 
4966  | 0  |         reader->errorFuncArg = NULL;  | 
4967  | 0  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
4968  | 0  |         if (reader->rngValidCtxt) { | 
4969  | 0  |             xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,  | 
4970  | 0  |                                      reader);  | 
4971  | 0  |             xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,  | 
4972  | 0  |                                                reader);  | 
4973  | 0  |         }  | 
4974  | 0  |         if (reader->xsdValidCtxt) { | 
4975  | 0  |             xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,  | 
4976  | 0  |                                     reader);  | 
4977  | 0  |             xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,  | 
4978  | 0  |                                               reader);  | 
4979  | 0  |         }  | 
4980  | 0  | #endif  | 
4981  | 0  |     }  | 
4982  | 0  | }  | 
4983  |  |  | 
4984  |  | /**  | 
4985  |  |  * xmlTextReaderIsValid:  | 
4986  |  |  * @reader:  the xmlTextReaderPtr used  | 
4987  |  |  *  | 
4988  |  |  * Retrieve the validity status from the parser context  | 
4989  |  |  *  | 
4990  |  |  * Returns the flag value 1 if valid, 0 if no, and -1 in case of error  | 
4991  |  |  */  | 
4992  |  | int  | 
4993  |  | xmlTextReaderIsValid(xmlTextReaderPtr reader)  | 
4994  | 0  | { | 
4995  | 0  |     if (reader == NULL)  | 
4996  | 0  |         return (-1);  | 
4997  | 0  | #ifdef LIBXML_SCHEMAS_ENABLED  | 
4998  | 0  |     if (reader->validate == XML_TEXTREADER_VALIDATE_RNG)  | 
4999  | 0  |         return (reader->rngValidErrors == 0);  | 
5000  | 0  |     if (reader->validate == XML_TEXTREADER_VALIDATE_XSD)  | 
5001  | 0  |         return (reader->xsdValidErrors == 0);  | 
5002  | 0  | #endif  | 
5003  | 0  |     if ((reader->ctxt != NULL) && (reader->ctxt->validate == 1))  | 
5004  | 0  |         return (reader->ctxt->valid);  | 
5005  | 0  |     return (0);  | 
5006  | 0  | }  | 
5007  |  |  | 
5008  |  | /**  | 
5009  |  |  * xmlTextReaderGetErrorHandler:  | 
5010  |  |  * @reader:  the xmlTextReaderPtr used  | 
5011  |  |  * @f:  the callback function or NULL is no callback has been registered  | 
5012  |  |  * @arg:    a user argument  | 
5013  |  |  *  | 
5014  |  |  * Retrieve the error callback function and user argument.  | 
5015  |  |  */  | 
5016  |  | void  | 
5017  |  | xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,  | 
5018  |  |                              xmlTextReaderErrorFunc * f, void **arg)  | 
5019  | 0  | { | 
5020  | 0  |     if (f != NULL)  | 
5021  | 0  |         *f = reader->errorFunc;  | 
5022  | 0  |     if (arg != NULL)  | 
5023  | 0  |         *arg = reader->errorFuncArg;  | 
5024  | 0  | }  | 
5025  |  | /************************************************************************  | 
5026  |  |  *                  *  | 
5027  |  |  *  New set (2.6.0) of simpler and more flexible APIs   *  | 
5028  |  |  *                  *  | 
5029  |  |  ************************************************************************/  | 
5030  |  |  | 
5031  |  | /**  | 
5032  |  |  * xmlTextReaderSetup:  | 
5033  |  |  * @reader:  an XML reader  | 
5034  |  |  * @input: xmlParserInputBufferPtr used to feed the reader, will  | 
5035  |  |  *         be destroyed with it.  | 
5036  |  |  * @URL:  the base URL to use for the document  | 
5037  |  |  * @encoding:  the document encoding, or NULL  | 
5038  |  |  * @options:  a combination of xmlParserOption  | 
5039  |  |  *  | 
5040  |  |  * Setup an XML reader with new options  | 
5041  |  |  *  | 
5042  |  |  * Returns 0 in case of success and -1 in case of error.  | 
5043  |  |  */  | 
5044  |  | int  | 
5045  |  | xmlTextReaderSetup(xmlTextReaderPtr reader,  | 
5046  |  |                    xmlParserInputBufferPtr input, const char *URL,  | 
5047  |  |                    const char *encoding, int options)  | 
5048  | 365k  | { | 
5049  | 365k  |     if (reader == NULL) { | 
5050  | 0  |         if (input != NULL)  | 
5051  | 0  |       xmlFreeParserInputBuffer(input);  | 
5052  | 0  |         return (-1);  | 
5053  | 0  |     }  | 
5054  |  |  | 
5055  |  |     /*  | 
5056  |  |      * we force the generation of compact text nodes on the reader  | 
5057  |  |      * since usr applications should never modify the tree  | 
5058  |  |      */  | 
5059  | 365k  |     options |= XML_PARSE_COMPACT;  | 
5060  |  |  | 
5061  | 365k  |     reader->doc = NULL;  | 
5062  | 365k  |     reader->entNr = 0;  | 
5063  | 365k  |     reader->parserFlags = options;  | 
5064  | 365k  |     reader->validate = XML_TEXTREADER_NOT_VALIDATE;  | 
5065  | 365k  |     if ((input != NULL) && (reader->input != NULL) &&  | 
5066  | 365k  |         (reader->allocs & XML_TEXTREADER_INPUT)) { | 
5067  | 0  |   xmlFreeParserInputBuffer(reader->input);  | 
5068  | 0  |   reader->input = NULL;  | 
5069  | 0  |   reader->allocs -= XML_TEXTREADER_INPUT;  | 
5070  | 0  |     }  | 
5071  | 365k  |     if (input != NULL) { | 
5072  | 0  |   reader->input = input;  | 
5073  | 0  |   reader->allocs |= XML_TEXTREADER_INPUT;  | 
5074  | 0  |     }  | 
5075  | 365k  |     if (reader->buffer == NULL)  | 
5076  | 0  |         reader->buffer = xmlBufCreateSize(100);  | 
5077  | 365k  |     if (reader->buffer == NULL) { | 
5078  | 0  |         xmlGenericError(xmlGenericErrorContext,  | 
5079  | 0  |                         "xmlTextReaderSetup : malloc failed\n");  | 
5080  | 0  |         return (-1);  | 
5081  | 0  |     }  | 
5082  |  |     /* no operation on a reader should require a huge buffer */  | 
5083  | 365k  |     xmlBufSetAllocationScheme(reader->buffer,  | 
5084  | 365k  |             XML_BUFFER_ALLOC_DOUBLEIT);  | 
5085  | 365k  |     if (reader->sax == NULL)  | 
5086  | 0  |   reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));  | 
5087  | 365k  |     if (reader->sax == NULL) { | 
5088  | 0  |         xmlGenericError(xmlGenericErrorContext,  | 
5089  | 0  |                         "xmlTextReaderSetup : malloc failed\n");  | 
5090  | 0  |         return (-1);  | 
5091  | 0  |     }  | 
5092  | 365k  |     xmlSAXVersion(reader->sax, 2);  | 
5093  | 365k  |     reader->startElement = reader->sax->startElement;  | 
5094  | 365k  |     reader->sax->startElement = xmlTextReaderStartElement;  | 
5095  | 365k  |     reader->endElement = reader->sax->endElement;  | 
5096  | 365k  |     reader->sax->endElement = xmlTextReaderEndElement;  | 
5097  | 365k  | #ifdef LIBXML_SAX1_ENABLED  | 
5098  | 365k  |     if (reader->sax->initialized == XML_SAX2_MAGIC) { | 
5099  | 365k  | #endif /* LIBXML_SAX1_ENABLED */  | 
5100  | 365k  |         reader->startElementNs = reader->sax->startElementNs;  | 
5101  | 365k  |         reader->sax->startElementNs = xmlTextReaderStartElementNs;  | 
5102  | 365k  |         reader->endElementNs = reader->sax->endElementNs;  | 
5103  | 365k  |         reader->sax->endElementNs = xmlTextReaderEndElementNs;  | 
5104  | 365k  | #ifdef LIBXML_SAX1_ENABLED  | 
5105  | 365k  |     } else { | 
5106  | 0  |         reader->startElementNs = NULL;  | 
5107  | 0  |         reader->endElementNs = NULL;  | 
5108  | 0  |     }  | 
5109  | 365k  | #endif /* LIBXML_SAX1_ENABLED */  | 
5110  | 365k  |     reader->characters = reader->sax->characters;  | 
5111  | 365k  |     reader->sax->characters = xmlTextReaderCharacters;  | 
5112  | 365k  |     reader->sax->ignorableWhitespace = xmlTextReaderCharacters;  | 
5113  | 365k  |     reader->cdataBlock = reader->sax->cdataBlock;  | 
5114  | 365k  |     reader->sax->cdataBlock = xmlTextReaderCDataBlock;  | 
5115  |  |  | 
5116  | 365k  |     reader->mode = XML_TEXTREADER_MODE_INITIAL;  | 
5117  | 365k  |     reader->node = NULL;  | 
5118  | 365k  |     reader->curnode = NULL;  | 
5119  | 365k  |     if (input != NULL) { | 
5120  | 0  |         if (xmlBufUse(reader->input->buffer) < 4) { | 
5121  | 0  |             xmlParserInputBufferRead(input, 4);  | 
5122  | 0  |         }  | 
5123  | 0  |         if (reader->ctxt == NULL) { | 
5124  | 0  |             if (xmlBufUse(reader->input->buffer) >= 4) { | 
5125  | 0  |                 reader->ctxt = xmlCreatePushParserCtxt(reader->sax, NULL,  | 
5126  | 0  |            (const char *) xmlBufContent(reader->input->buffer),  | 
5127  | 0  |                                       4, URL);  | 
5128  | 0  |                 reader->base = 0;  | 
5129  | 0  |                 reader->cur = 4;  | 
5130  | 0  |             } else { | 
5131  | 0  |                 reader->ctxt =  | 
5132  | 0  |                     xmlCreatePushParserCtxt(reader->sax, NULL, NULL, 0, URL);  | 
5133  | 0  |                 reader->base = 0;  | 
5134  | 0  |                 reader->cur = 0;  | 
5135  | 0  |             }  | 
5136  | 0  |         } else { | 
5137  | 0  |       xmlParserInputPtr inputStream;  | 
5138  | 0  |       xmlParserInputBufferPtr buf;  | 
5139  | 0  |       xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;  | 
5140  |  | 
  | 
5141  | 0  |       xmlCtxtReset(reader->ctxt);  | 
5142  | 0  |       buf = xmlAllocParserInputBuffer(enc);  | 
5143  | 0  |       if (buf == NULL) return(-1);  | 
5144  | 0  |       inputStream = xmlNewInputStream(reader->ctxt);  | 
5145  | 0  |       if (inputStream == NULL) { | 
5146  | 0  |     xmlFreeParserInputBuffer(buf);  | 
5147  | 0  |     return(-1);  | 
5148  | 0  |       }  | 
5149  |  |  | 
5150  | 0  |       if (URL == NULL)  | 
5151  | 0  |     inputStream->filename = NULL;  | 
5152  | 0  |       else  | 
5153  | 0  |     inputStream->filename = (char *)  | 
5154  | 0  |         xmlCanonicPath((const xmlChar *) URL);  | 
5155  | 0  |       inputStream->buf = buf;  | 
5156  | 0  |             xmlBufResetInput(buf->buffer, inputStream);  | 
5157  |  | 
  | 
5158  | 0  |       inputPush(reader->ctxt, inputStream);  | 
5159  | 0  |       reader->cur = 0;  | 
5160  | 0  |   }  | 
5161  | 0  |         if (reader->ctxt == NULL) { | 
5162  | 0  |             xmlGenericError(xmlGenericErrorContext,  | 
5163  | 0  |                             "xmlTextReaderSetup : malloc failed\n");  | 
5164  | 0  |             return (-1);  | 
5165  | 0  |         }  | 
5166  | 0  |     }  | 
5167  | 365k  |     if (reader->dict != NULL) { | 
5168  | 365k  |         if (reader->ctxt->dict != NULL) { | 
5169  | 365k  |       if (reader->dict != reader->ctxt->dict) { | 
5170  | 0  |     xmlDictFree(reader->dict);  | 
5171  | 0  |     reader->dict = reader->ctxt->dict;  | 
5172  | 0  |       }  | 
5173  | 365k  |   } else { | 
5174  | 0  |       reader->ctxt->dict = reader->dict;  | 
5175  | 0  |   }  | 
5176  | 365k  |     } else { | 
5177  | 0  |   if (reader->ctxt->dict == NULL)  | 
5178  | 0  |       reader->ctxt->dict = xmlDictCreate();  | 
5179  | 0  |         reader->dict = reader->ctxt->dict;  | 
5180  | 0  |     }  | 
5181  | 365k  |     reader->ctxt->_private = reader;  | 
5182  | 365k  |     reader->ctxt->linenumbers = 1;  | 
5183  | 365k  |     reader->ctxt->dictNames = 1;  | 
5184  |  |     /*  | 
5185  |  |      * use the parser dictionary to allocate all elements and attributes names  | 
5186  |  |      */  | 
5187  | 365k  |     reader->ctxt->docdict = 1;  | 
5188  | 365k  |     reader->ctxt->parseMode = XML_PARSE_READER;  | 
5189  |  |  | 
5190  | 365k  | #ifdef LIBXML_XINCLUDE_ENABLED  | 
5191  | 365k  |     if (reader->xincctxt != NULL) { | 
5192  | 0  |   xmlXIncludeFreeContext(reader->xincctxt);  | 
5193  | 0  |   reader->xincctxt = NULL;  | 
5194  | 0  |     }  | 
5195  | 365k  |     if (options & XML_PARSE_XINCLUDE) { | 
5196  | 0  |         reader->xinclude = 1;  | 
5197  | 0  |   reader->xinclude_name = xmlDictLookup(reader->dict, XINCLUDE_NODE, -1);  | 
5198  | 0  |   options -= XML_PARSE_XINCLUDE;  | 
5199  | 0  |     } else  | 
5200  | 365k  |         reader->xinclude = 0;  | 
5201  | 365k  |     reader->in_xinclude = 0;  | 
5202  | 365k  | #endif  | 
5203  | 365k  | #ifdef LIBXML_PATTERN_ENABLED  | 
5204  | 365k  |     if (reader->patternTab == NULL) { | 
5205  | 365k  |         reader->patternNr = 0;  | 
5206  | 365k  |   reader->patternMax = 0;  | 
5207  | 365k  |     }  | 
5208  | 365k  |     while (reader->patternNr > 0) { | 
5209  | 0  |         reader->patternNr--;  | 
5210  | 0  |   if (reader->patternTab[reader->patternNr] != NULL) { | 
5211  | 0  |       xmlFreePattern(reader->patternTab[reader->patternNr]);  | 
5212  | 0  |             reader->patternTab[reader->patternNr] = NULL;  | 
5213  | 0  |   }  | 
5214  | 0  |     }  | 
5215  | 365k  | #endif  | 
5216  |  |  | 
5217  | 365k  |     if (options & XML_PARSE_DTDVALID)  | 
5218  | 150k  |         reader->validate = XML_TEXTREADER_VALIDATE_DTD;  | 
5219  |  |  | 
5220  | 365k  |     xmlCtxtUseOptions(reader->ctxt, options);  | 
5221  | 365k  |     if (encoding != NULL) { | 
5222  | 0  |         xmlCharEncodingHandlerPtr hdlr;  | 
5223  |  | 
  | 
5224  | 0  |         hdlr = xmlFindCharEncodingHandler(encoding);  | 
5225  | 0  |         if (hdlr != NULL)  | 
5226  | 0  |             xmlSwitchToEncoding(reader->ctxt, hdlr);  | 
5227  | 0  |     }  | 
5228  | 365k  |     if ((URL != NULL) && (reader->ctxt->input != NULL) &&  | 
5229  | 365k  |         (reader->ctxt->input->filename == NULL))  | 
5230  | 0  |         reader->ctxt->input->filename = (char *)  | 
5231  | 0  |             xmlStrdup((const xmlChar *) URL);  | 
5232  |  |  | 
5233  | 365k  |     reader->doc = NULL;  | 
5234  |  |  | 
5235  | 365k  |     return (0);  | 
5236  | 365k  | }  | 
5237  |  |  | 
5238  |  | /**  | 
5239  |  |  * xmlTextReaderByteConsumed:  | 
5240  |  |  * @reader: an XML reader  | 
5241  |  |  *  | 
5242  |  |  * This function provides the current index of the parser used  | 
5243  |  |  * by the reader, relative to the start of the current entity.  | 
5244  |  |  * This function actually just wraps a call to xmlBytesConsumed()  | 
5245  |  |  * for the parser context associated with the reader.  | 
5246  |  |  * See xmlBytesConsumed() for more information.  | 
5247  |  |  *  | 
5248  |  |  * Returns the index in bytes from the beginning of the entity or -1  | 
5249  |  |  *         in case the index could not be computed.  | 
5250  |  |  */  | 
5251  |  | long  | 
5252  | 0  | xmlTextReaderByteConsumed(xmlTextReaderPtr reader) { | 
5253  | 0  |     if ((reader == NULL) || (reader->ctxt == NULL))  | 
5254  | 0  |         return(-1);  | 
5255  | 0  |     return(xmlByteConsumed(reader->ctxt));  | 
5256  | 0  | }  | 
5257  |  |  | 
5258  |  |  | 
5259  |  | /**  | 
5260  |  |  * xmlReaderWalker:  | 
5261  |  |  * @doc:  a preparsed document  | 
5262  |  |  *  | 
5263  |  |  * Create an xmltextReader for a preparsed document.  | 
5264  |  |  *  | 
5265  |  |  * Returns the new reader or NULL in case of error.  | 
5266  |  |  */  | 
5267  |  | xmlTextReaderPtr  | 
5268  |  | xmlReaderWalker(xmlDocPtr doc)  | 
5269  | 0  | { | 
5270  | 0  |     xmlTextReaderPtr ret;  | 
5271  |  | 
  | 
5272  | 0  |     if (doc == NULL)  | 
5273  | 0  |         return(NULL);  | 
5274  |  |  | 
5275  | 0  |     ret = xmlMalloc(sizeof(xmlTextReader));  | 
5276  | 0  |     if (ret == NULL) { | 
5277  | 0  |         xmlGenericError(xmlGenericErrorContext,  | 
5278  | 0  |     "xmlNewTextReader : malloc failed\n");  | 
5279  | 0  |   return(NULL);  | 
5280  | 0  |     }  | 
5281  | 0  |     memset(ret, 0, sizeof(xmlTextReader));  | 
5282  | 0  |     ret->entNr = 0;  | 
5283  | 0  |     ret->input = NULL;  | 
5284  | 0  |     ret->mode = XML_TEXTREADER_MODE_INITIAL;  | 
5285  | 0  |     ret->node = NULL;  | 
5286  | 0  |     ret->curnode = NULL;  | 
5287  | 0  |     ret->base = 0;  | 
5288  | 0  |     ret->cur = 0;  | 
5289  | 0  |     ret->allocs = XML_TEXTREADER_CTXT;  | 
5290  | 0  |     ret->doc = doc;  | 
5291  | 0  |     ret->state = XML_TEXTREADER_START;  | 
5292  | 0  |     ret->dict = xmlDictCreate();  | 
5293  | 0  |     return(ret);  | 
5294  | 0  | }  | 
5295  |  |  | 
5296  |  | /**  | 
5297  |  |  * xmlReaderForDoc:  | 
5298  |  |  * @cur:  a pointer to a zero terminated string  | 
5299  |  |  * @URL:  the base URL to use for the document  | 
5300  |  |  * @encoding:  the document encoding, or NULL  | 
5301  |  |  * @options:  a combination of xmlParserOption  | 
5302  |  |  *  | 
5303  |  |  * Create an xmltextReader for an XML in-memory document.  | 
5304  |  |  * The parsing flags @options are a combination of xmlParserOption.  | 
5305  |  |  *  | 
5306  |  |  * Returns the new reader or NULL in case of error.  | 
5307  |  |  */  | 
5308  |  | xmlTextReaderPtr  | 
5309  |  | xmlReaderForDoc(const xmlChar * cur, const char *URL, const char *encoding,  | 
5310  |  |                 int options)  | 
5311  | 0  | { | 
5312  | 0  |     int len;  | 
5313  |  | 
  | 
5314  | 0  |     if (cur == NULL)  | 
5315  | 0  |         return (NULL);  | 
5316  | 0  |     len = xmlStrlen(cur);  | 
5317  |  | 
  | 
5318  | 0  |     return (xmlReaderForMemory  | 
5319  | 0  |             ((const char *) cur, len, URL, encoding, options));  | 
5320  | 0  | }  | 
5321  |  |  | 
5322  |  | /**  | 
5323  |  |  * xmlReaderForFile:  | 
5324  |  |  * @filename:  a file or URL  | 
5325  |  |  * @encoding:  the document encoding, or NULL  | 
5326  |  |  * @options:  a combination of xmlParserOption  | 
5327  |  |  *  | 
5328  |  |  * parse an XML file from the filesystem or the network.  | 
5329  |  |  * The parsing flags @options are a combination of xmlParserOption.  | 
5330  |  |  *  | 
5331  |  |  * Returns the new reader or NULL in case of error.  | 
5332  |  |  */  | 
5333  |  | xmlTextReaderPtr  | 
5334  |  | xmlReaderForFile(const char *filename, const char *encoding, int options)  | 
5335  | 0  | { | 
5336  | 0  |     xmlTextReaderPtr reader;  | 
5337  |  | 
  | 
5338  | 0  |     reader = xmlNewTextReaderFilename(filename);  | 
5339  | 0  |     if (reader == NULL)  | 
5340  | 0  |         return (NULL);  | 
5341  | 0  |     xmlTextReaderSetup(reader, NULL, NULL, encoding, options);  | 
5342  | 0  |     return (reader);  | 
5343  | 0  | }  | 
5344  |  |  | 
5345  |  | /**  | 
5346  |  |  * xmlReaderForMemory:  | 
5347  |  |  * @buffer:  a pointer to a char array  | 
5348  |  |  * @size:  the size of the array  | 
5349  |  |  * @URL:  the base URL to use for the document  | 
5350  |  |  * @encoding:  the document encoding, or NULL  | 
5351  |  |  * @options:  a combination of xmlParserOption  | 
5352  |  |  *  | 
5353  |  |  * Create an xmltextReader for an XML in-memory document.  | 
5354  |  |  * The parsing flags @options are a combination of xmlParserOption.  | 
5355  |  |  *  | 
5356  |  |  * Returns the new reader or NULL in case of error.  | 
5357  |  |  */  | 
5358  |  | xmlTextReaderPtr  | 
5359  |  | xmlReaderForMemory(const char *buffer, int size, const char *URL,  | 
5360  |  |                    const char *encoding, int options)  | 
5361  | 365k  | { | 
5362  | 365k  |     xmlTextReaderPtr reader;  | 
5363  | 365k  |     xmlParserInputBufferPtr buf;  | 
5364  |  |  | 
5365  | 365k  |     buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);  | 
5366  | 365k  |     if (buf == NULL) { | 
5367  | 0  |         return (NULL);  | 
5368  | 0  |     }  | 
5369  | 365k  |     reader = xmlNewTextReader(buf, URL);  | 
5370  | 365k  |     if (reader == NULL) { | 
5371  | 0  |         xmlFreeParserInputBuffer(buf);  | 
5372  | 0  |         return (NULL);  | 
5373  | 0  |     }  | 
5374  | 365k  |     reader->allocs |= XML_TEXTREADER_INPUT;  | 
5375  | 365k  |     xmlTextReaderSetup(reader, NULL, URL, encoding, options);  | 
5376  | 365k  |     return (reader);  | 
5377  | 365k  | }  | 
5378  |  |  | 
5379  |  | /**  | 
5380  |  |  * xmlReaderForFd:  | 
5381  |  |  * @fd:  an open file descriptor  | 
5382  |  |  * @URL:  the base URL to use for the document  | 
5383  |  |  * @encoding:  the document encoding, or NULL  | 
5384  |  |  * @options:  a combination of xmlParserOption  | 
5385  |  |  *  | 
5386  |  |  * Create an xmltextReader for an XML from a file descriptor.  | 
5387  |  |  * The parsing flags @options are a combination of xmlParserOption.  | 
5388  |  |  * NOTE that the file descriptor will not be closed when the  | 
5389  |  |  *      reader is closed or reset.  | 
5390  |  |  *  | 
5391  |  |  * Returns the new reader or NULL in case of error.  | 
5392  |  |  */  | 
5393  |  | xmlTextReaderPtr  | 
5394  |  | xmlReaderForFd(int fd, const char *URL, const char *encoding, int options)  | 
5395  | 0  | { | 
5396  | 0  |     xmlTextReaderPtr reader;  | 
5397  | 0  |     xmlParserInputBufferPtr input;  | 
5398  |  | 
  | 
5399  | 0  |     if (fd < 0)  | 
5400  | 0  |         return (NULL);  | 
5401  |  |  | 
5402  | 0  |     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);  | 
5403  | 0  |     if (input == NULL)  | 
5404  | 0  |         return (NULL);  | 
5405  | 0  |     input->closecallback = NULL;  | 
5406  | 0  |     reader = xmlNewTextReader(input, URL);  | 
5407  | 0  |     if (reader == NULL) { | 
5408  | 0  |         xmlFreeParserInputBuffer(input);  | 
5409  | 0  |         return (NULL);  | 
5410  | 0  |     }  | 
5411  | 0  |     reader->allocs |= XML_TEXTREADER_INPUT;  | 
5412  | 0  |     xmlTextReaderSetup(reader, NULL, URL, encoding, options);  | 
5413  | 0  |     return (reader);  | 
5414  | 0  | }  | 
5415  |  |  | 
5416  |  | /**  | 
5417  |  |  * xmlReaderForIO:  | 
5418  |  |  * @ioread:  an I/O read function  | 
5419  |  |  * @ioclose:  an I/O close function  | 
5420  |  |  * @ioctx:  an I/O handler  | 
5421  |  |  * @URL:  the base URL to use for the document  | 
5422  |  |  * @encoding:  the document encoding, or NULL  | 
5423  |  |  * @options:  a combination of xmlParserOption  | 
5424  |  |  *  | 
5425  |  |  * Create an xmltextReader for an XML document from I/O functions and source.  | 
5426  |  |  * The parsing flags @options are a combination of xmlParserOption.  | 
5427  |  |  *  | 
5428  |  |  * Returns the new reader or NULL in case of error.  | 
5429  |  |  */  | 
5430  |  | xmlTextReaderPtr  | 
5431  |  | xmlReaderForIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,  | 
5432  |  |                void *ioctx, const char *URL, const char *encoding,  | 
5433  |  |                int options)  | 
5434  | 0  | { | 
5435  | 0  |     xmlTextReaderPtr reader;  | 
5436  | 0  |     xmlParserInputBufferPtr input;  | 
5437  |  | 
  | 
5438  | 0  |     if (ioread == NULL)  | 
5439  | 0  |         return (NULL);  | 
5440  |  |  | 
5441  | 0  |     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,  | 
5442  | 0  |                                          XML_CHAR_ENCODING_NONE);  | 
5443  | 0  |     if (input == NULL) { | 
5444  | 0  |         if (ioclose != NULL)  | 
5445  | 0  |             ioclose(ioctx);  | 
5446  | 0  |         return (NULL);  | 
5447  | 0  |     }  | 
5448  | 0  |     reader = xmlNewTextReader(input, URL);  | 
5449  | 0  |     if (reader == NULL) { | 
5450  | 0  |         xmlFreeParserInputBuffer(input);  | 
5451  | 0  |         return (NULL);  | 
5452  | 0  |     }  | 
5453  | 0  |     reader->allocs |= XML_TEXTREADER_INPUT;  | 
5454  | 0  |     xmlTextReaderSetup(reader, NULL, URL, encoding, options);  | 
5455  | 0  |     return (reader);  | 
5456  | 0  | }  | 
5457  |  |  | 
5458  |  | /**  | 
5459  |  |  * xmlReaderNewWalker:  | 
5460  |  |  * @reader:  an XML reader  | 
5461  |  |  * @doc:  a preparsed document  | 
5462  |  |  *  | 
5463  |  |  * Setup an xmltextReader to parse a preparsed XML document.  | 
5464  |  |  * This reuses the existing @reader xmlTextReader.  | 
5465  |  |  *  | 
5466  |  |  * Returns 0 in case of success and -1 in case of error  | 
5467  |  |  */  | 
5468  |  | int  | 
5469  |  | xmlReaderNewWalker(xmlTextReaderPtr reader, xmlDocPtr doc)  | 
5470  | 0  | { | 
5471  | 0  |     if (doc == NULL)  | 
5472  | 0  |         return (-1);  | 
5473  | 0  |     if (reader == NULL)  | 
5474  | 0  |         return (-1);  | 
5475  |  |  | 
5476  | 0  |     if (reader->input != NULL) { | 
5477  | 0  |         xmlFreeParserInputBuffer(reader->input);  | 
5478  | 0  |     }  | 
5479  | 0  |     if (reader->ctxt != NULL) { | 
5480  | 0  |   xmlCtxtReset(reader->ctxt);  | 
5481  | 0  |     }  | 
5482  |  | 
  | 
5483  | 0  |     reader->entNr = 0;  | 
5484  | 0  |     reader->input = NULL;  | 
5485  | 0  |     reader->mode = XML_TEXTREADER_MODE_INITIAL;  | 
5486  | 0  |     reader->node = NULL;  | 
5487  | 0  |     reader->curnode = NULL;  | 
5488  | 0  |     reader->base = 0;  | 
5489  | 0  |     reader->cur = 0;  | 
5490  | 0  |     reader->allocs = XML_TEXTREADER_CTXT;  | 
5491  | 0  |     reader->doc = doc;  | 
5492  | 0  |     reader->state = XML_TEXTREADER_START;  | 
5493  | 0  |     if (reader->dict == NULL) { | 
5494  | 0  |         if ((reader->ctxt != NULL) && (reader->ctxt->dict != NULL))  | 
5495  | 0  |       reader->dict = reader->ctxt->dict;  | 
5496  | 0  |   else  | 
5497  | 0  |       reader->dict = xmlDictCreate();  | 
5498  | 0  |     }  | 
5499  | 0  |     return(0);  | 
5500  | 0  | }  | 
5501  |  |  | 
5502  |  | /**  | 
5503  |  |  * xmlReaderNewDoc:  | 
5504  |  |  * @reader:  an XML reader  | 
5505  |  |  * @cur:  a pointer to a zero terminated string  | 
5506  |  |  * @URL:  the base URL to use for the document  | 
5507  |  |  * @encoding:  the document encoding, or NULL  | 
5508  |  |  * @options:  a combination of xmlParserOption  | 
5509  |  |  *  | 
5510  |  |  * Setup an xmltextReader to parse an XML in-memory document.  | 
5511  |  |  * The parsing flags @options are a combination of xmlParserOption.  | 
5512  |  |  * This reuses the existing @reader xmlTextReader.  | 
5513  |  |  *  | 
5514  |  |  * Returns 0 in case of success and -1 in case of error  | 
5515  |  |  */  | 
5516  |  | int  | 
5517  |  | xmlReaderNewDoc(xmlTextReaderPtr reader, const xmlChar * cur,  | 
5518  |  |                 const char *URL, const char *encoding, int options)  | 
5519  | 0  | { | 
5520  |  | 
  | 
5521  | 0  |     int len;  | 
5522  |  | 
  | 
5523  | 0  |     if (cur == NULL)  | 
5524  | 0  |         return (-1);  | 
5525  | 0  |     if (reader == NULL)  | 
5526  | 0  |         return (-1);  | 
5527  |  |  | 
5528  | 0  |     len = xmlStrlen(cur);  | 
5529  | 0  |     return (xmlReaderNewMemory(reader, (const char *)cur, len,  | 
5530  | 0  |                                URL, encoding, options));  | 
5531  | 0  | }  | 
5532  |  |  | 
5533  |  | /**  | 
5534  |  |  * xmlReaderNewFile:  | 
5535  |  |  * @reader:  an XML reader  | 
5536  |  |  * @filename:  a file or URL  | 
5537  |  |  * @encoding:  the document encoding, or NULL  | 
5538  |  |  * @options:  a combination of xmlParserOption  | 
5539  |  |  *  | 
5540  |  |  * parse an XML file from the filesystem or the network.  | 
5541  |  |  * The parsing flags @options are a combination of xmlParserOption.  | 
5542  |  |  * This reuses the existing @reader xmlTextReader.  | 
5543  |  |  *  | 
5544  |  |  * Returns 0 in case of success and -1 in case of error  | 
5545  |  |  */  | 
5546  |  | int  | 
5547  |  | xmlReaderNewFile(xmlTextReaderPtr reader, const char *filename,  | 
5548  |  |                  const char *encoding, int options)  | 
5549  | 0  | { | 
5550  | 0  |     xmlParserInputBufferPtr input;  | 
5551  |  | 
  | 
5552  | 0  |     if (filename == NULL)  | 
5553  | 0  |         return (-1);  | 
5554  | 0  |     if (reader == NULL)  | 
5555  | 0  |         return (-1);  | 
5556  |  |  | 
5557  | 0  |     input =  | 
5558  | 0  |         xmlParserInputBufferCreateFilename(filename,  | 
5559  | 0  |                                            XML_CHAR_ENCODING_NONE);  | 
5560  | 0  |     if (input == NULL)  | 
5561  | 0  |         return (-1);  | 
5562  | 0  |     return (xmlTextReaderSetup(reader, input, filename, encoding, options));  | 
5563  | 0  | }  | 
5564  |  |  | 
5565  |  | /**  | 
5566  |  |  * xmlReaderNewMemory:  | 
5567  |  |  * @reader:  an XML reader  | 
5568  |  |  * @buffer:  a pointer to a char array  | 
5569  |  |  * @size:  the size of the array  | 
5570  |  |  * @URL:  the base URL to use for the document  | 
5571  |  |  * @encoding:  the document encoding, or NULL  | 
5572  |  |  * @options:  a combination of xmlParserOption  | 
5573  |  |  *  | 
5574  |  |  * Setup an xmltextReader to parse an XML in-memory document.  | 
5575  |  |  * The parsing flags @options are a combination of xmlParserOption.  | 
5576  |  |  * This reuses the existing @reader xmlTextReader.  | 
5577  |  |  *  | 
5578  |  |  * Returns 0 in case of success and -1 in case of error  | 
5579  |  |  */  | 
5580  |  | int  | 
5581  |  | xmlReaderNewMemory(xmlTextReaderPtr reader, const char *buffer, int size,  | 
5582  |  |                    const char *URL, const char *encoding, int options)  | 
5583  | 0  | { | 
5584  | 0  |     xmlParserInputBufferPtr input;  | 
5585  |  | 
  | 
5586  | 0  |     if (reader == NULL)  | 
5587  | 0  |         return (-1);  | 
5588  | 0  |     if (buffer == NULL)  | 
5589  | 0  |         return (-1);  | 
5590  |  |  | 
5591  | 0  |     input = xmlParserInputBufferCreateMem(buffer, size,  | 
5592  | 0  |                                       XML_CHAR_ENCODING_NONE);  | 
5593  | 0  |     if (input == NULL) { | 
5594  | 0  |         return (-1);  | 
5595  | 0  |     }  | 
5596  | 0  |     return (xmlTextReaderSetup(reader, input, URL, encoding, options));  | 
5597  | 0  | }  | 
5598  |  |  | 
5599  |  | /**  | 
5600  |  |  * xmlReaderNewFd:  | 
5601  |  |  * @reader:  an XML reader  | 
5602  |  |  * @fd:  an open file descriptor  | 
5603  |  |  * @URL:  the base URL to use for the document  | 
5604  |  |  * @encoding:  the document encoding, or NULL  | 
5605  |  |  * @options:  a combination of xmlParserOption  | 
5606  |  |  *  | 
5607  |  |  * Setup an xmltextReader to parse an XML from a file descriptor.  | 
5608  |  |  * NOTE that the file descriptor will not be closed when the  | 
5609  |  |  *      reader is closed or reset.  | 
5610  |  |  * The parsing flags @options are a combination of xmlParserOption.  | 
5611  |  |  * This reuses the existing @reader xmlTextReader.  | 
5612  |  |  *  | 
5613  |  |  * Returns 0 in case of success and -1 in case of error  | 
5614  |  |  */  | 
5615  |  | int  | 
5616  |  | xmlReaderNewFd(xmlTextReaderPtr reader, int fd,  | 
5617  |  |                const char *URL, const char *encoding, int options)  | 
5618  | 0  | { | 
5619  | 0  |     xmlParserInputBufferPtr input;  | 
5620  |  | 
  | 
5621  | 0  |     if (fd < 0)  | 
5622  | 0  |         return (-1);  | 
5623  | 0  |     if (reader == NULL)  | 
5624  | 0  |         return (-1);  | 
5625  |  |  | 
5626  | 0  |     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);  | 
5627  | 0  |     if (input == NULL)  | 
5628  | 0  |         return (-1);  | 
5629  | 0  |     input->closecallback = NULL;  | 
5630  | 0  |     return (xmlTextReaderSetup(reader, input, URL, encoding, options));  | 
5631  | 0  | }  | 
5632  |  |  | 
5633  |  | /**  | 
5634  |  |  * xmlReaderNewIO:  | 
5635  |  |  * @reader:  an XML reader  | 
5636  |  |  * @ioread:  an I/O read function  | 
5637  |  |  * @ioclose:  an I/O close function  | 
5638  |  |  * @ioctx:  an I/O handler  | 
5639  |  |  * @URL:  the base URL to use for the document  | 
5640  |  |  * @encoding:  the document encoding, or NULL  | 
5641  |  |  * @options:  a combination of xmlParserOption  | 
5642  |  |  *  | 
5643  |  |  * Setup an xmltextReader to parse an XML document from I/O functions  | 
5644  |  |  * and source.  | 
5645  |  |  * The parsing flags @options are a combination of xmlParserOption.  | 
5646  |  |  * This reuses the existing @reader xmlTextReader.  | 
5647  |  |  *  | 
5648  |  |  * Returns 0 in case of success and -1 in case of error  | 
5649  |  |  */  | 
5650  |  | int  | 
5651  |  | xmlReaderNewIO(xmlTextReaderPtr reader, xmlInputReadCallback ioread,  | 
5652  |  |                xmlInputCloseCallback ioclose, void *ioctx,  | 
5653  |  |                const char *URL, const char *encoding, int options)  | 
5654  | 0  | { | 
5655  | 0  |     xmlParserInputBufferPtr input;  | 
5656  |  | 
  | 
5657  | 0  |     if (ioread == NULL)  | 
5658  | 0  |         return (-1);  | 
5659  | 0  |     if (reader == NULL)  | 
5660  | 0  |         return (-1);  | 
5661  |  |  | 
5662  | 0  |     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,  | 
5663  | 0  |                                          XML_CHAR_ENCODING_NONE);  | 
5664  | 0  |     if (input == NULL) { | 
5665  | 0  |         if (ioclose != NULL)  | 
5666  | 0  |             ioclose(ioctx);  | 
5667  | 0  |         return (-1);  | 
5668  | 0  |     }  | 
5669  | 0  |     return (xmlTextReaderSetup(reader, input, URL, encoding, options));  | 
5670  | 0  | }  | 
5671  |  |  | 
5672  |  | /************************************************************************  | 
5673  |  |  *                  *  | 
5674  |  |  *      Utilities         *  | 
5675  |  |  *                  *  | 
5676  |  |  ************************************************************************/  | 
5677  |  | #ifdef NOT_USED_YET  | 
5678  |  |  | 
5679  |  | /**  | 
5680  |  |  * xmlBase64Decode:  | 
5681  |  |  * @in:  the input buffer  | 
5682  |  |  * @inlen:  the size of the input (in), the size read from it (out)  | 
5683  |  |  * @to:  the output buffer  | 
5684  |  |  * @tolen:  the size of the output (in), the size written to (out)  | 
5685  |  |  *  | 
5686  |  |  * Base64 decoder, reads from @in and save in @to  | 
5687  |  |  * TODO: tell jody when this is actually exported  | 
5688  |  |  *  | 
5689  |  |  * Returns 0 if all the input was consumer, 1 if the Base64 end was reached,  | 
5690  |  |  *         2 if there wasn't enough space on the output or -1 in case of error.  | 
5691  |  |  */  | 
5692  |  | static int  | 
5693  |  | xmlBase64Decode(const unsigned char *in, unsigned long *inlen,  | 
5694  |  |                 unsigned char *to, unsigned long *tolen)  | 
5695  |  | { | 
5696  |  |     unsigned long incur;        /* current index in in[] */  | 
5697  |  |  | 
5698  |  |     unsigned long inblk;        /* last block index in in[] */  | 
5699  |  |  | 
5700  |  |     unsigned long outcur;       /* current index in out[] */  | 
5701  |  |  | 
5702  |  |     unsigned long inmax;        /* size of in[] */  | 
5703  |  |  | 
5704  |  |     unsigned long outmax;       /* size of out[] */  | 
5705  |  |  | 
5706  |  |     unsigned char cur;          /* the current value read from in[] */  | 
5707  |  |  | 
5708  |  |     unsigned char intmp[4], outtmp[4];  /* temporary buffers for the convert */  | 
5709  |  |  | 
5710  |  |     int nbintmp;                /* number of byte in intmp[] */  | 
5711  |  |  | 
5712  |  |     int is_ignore;              /* cur should be ignored */  | 
5713  |  |  | 
5714  |  |     int is_end = 0;             /* the end of the base64 was found */  | 
5715  |  |  | 
5716  |  |     int retval = 1;  | 
5717  |  |  | 
5718  |  |     int i;  | 
5719  |  |  | 
5720  |  |     if ((in == NULL) || (inlen == NULL) || (to == NULL) || (tolen == NULL))  | 
5721  |  |         return (-1);  | 
5722  |  |  | 
5723  |  |     incur = 0;  | 
5724  |  |     inblk = 0;  | 
5725  |  |     outcur = 0;  | 
5726  |  |     inmax = *inlen;  | 
5727  |  |     outmax = *tolen;  | 
5728  |  |     nbintmp = 0;  | 
5729  |  |  | 
5730  |  |     while (1) { | 
5731  |  |         if (incur >= inmax)  | 
5732  |  |             break;  | 
5733  |  |         cur = in[incur++];  | 
5734  |  |         is_ignore = 0;  | 
5735  |  |         if ((cur >= 'A') && (cur <= 'Z'))  | 
5736  |  |             cur = cur - 'A';  | 
5737  |  |         else if ((cur >= 'a') && (cur <= 'z'))  | 
5738  |  |             cur = cur - 'a' + 26;  | 
5739  |  |         else if ((cur >= '0') && (cur <= '9'))  | 
5740  |  |             cur = cur - '0' + 52;  | 
5741  |  |         else if (cur == '+')  | 
5742  |  |             cur = 62;  | 
5743  |  |         else if (cur == '/')  | 
5744  |  |             cur = 63;  | 
5745  |  |         else if (cur == '.')  | 
5746  |  |             cur = 0;  | 
5747  |  |         else if (cur == '=')    /*no op , end of the base64 stream */  | 
5748  |  |             is_end = 1;  | 
5749  |  |         else { | 
5750  |  |             is_ignore = 1;  | 
5751  |  |             if (nbintmp == 0)  | 
5752  |  |                 inblk = incur;  | 
5753  |  |         }  | 
5754  |  |  | 
5755  |  |         if (!is_ignore) { | 
5756  |  |             int nbouttmp = 3;  | 
5757  |  |  | 
5758  |  |             int is_break = 0;  | 
5759  |  |  | 
5760  |  |             if (is_end) { | 
5761  |  |                 if (nbintmp == 0)  | 
5762  |  |                     break;  | 
5763  |  |                 if ((nbintmp == 1) || (nbintmp == 2))  | 
5764  |  |                     nbouttmp = 1;  | 
5765  |  |                 else  | 
5766  |  |                     nbouttmp = 2;  | 
5767  |  |                 nbintmp = 3;  | 
5768  |  |                 is_break = 1;  | 
5769  |  |             }  | 
5770  |  |             intmp[nbintmp++] = cur;  | 
5771  |  |             /*  | 
5772  |  |              * if intmp is full, push the 4byte sequence as a 3 byte  | 
5773  |  |              * sequence out  | 
5774  |  |              */  | 
5775  |  |             if (nbintmp == 4) { | 
5776  |  |                 nbintmp = 0;  | 
5777  |  |                 outtmp[0] = (intmp[0] << 2) | ((intmp[1] & 0x30) >> 4);  | 
5778  |  |                 outtmp[1] =  | 
5779  |  |                     ((intmp[1] & 0x0F) << 4) | ((intmp[2] & 0x3C) >> 2);  | 
5780  |  |                 outtmp[2] = ((intmp[2] & 0x03) << 6) | (intmp[3] & 0x3F);  | 
5781  |  |                 if (outcur + 3 >= outmax) { | 
5782  |  |                     retval = 2;  | 
5783  |  |                     break;  | 
5784  |  |                 }  | 
5785  |  |  | 
5786  |  |                 for (i = 0; i < nbouttmp; i++)  | 
5787  |  |                     to[outcur++] = outtmp[i];  | 
5788  |  |                 inblk = incur;  | 
5789  |  |             }  | 
5790  |  |  | 
5791  |  |             if (is_break) { | 
5792  |  |                 retval = 0;  | 
5793  |  |                 break;  | 
5794  |  |             }  | 
5795  |  |         }  | 
5796  |  |     }  | 
5797  |  |  | 
5798  |  |     *tolen = outcur;  | 
5799  |  |     *inlen = inblk;  | 
5800  |  |     return (retval);  | 
5801  |  | }  | 
5802  |  |  | 
5803  |  | /*  | 
5804  |  |  * Test routine for the xmlBase64Decode function  | 
5805  |  |  */  | 
5806  |  | #if 0  | 
5807  |  | int  | 
5808  |  | main(int argc, char **argv)  | 
5809  |  | { | 
5810  |  |     char *input = "  VW4 gcGV0        \n      aXQgdGVzdCAuCg== ";  | 
5811  |  |  | 
5812  |  |     char output[100];  | 
5813  |  |  | 
5814  |  |     char output2[100];  | 
5815  |  |  | 
5816  |  |     char output3[100];  | 
5817  |  |  | 
5818  |  |     unsigned long inlen = strlen(input);  | 
5819  |  |  | 
5820  |  |     unsigned long outlen = 100;  | 
5821  |  |  | 
5822  |  |     int ret;  | 
5823  |  |  | 
5824  |  |     unsigned long cons, tmp, tmp2, prod;  | 
5825  |  |  | 
5826  |  |     /*  | 
5827  |  |      * Direct  | 
5828  |  |      */  | 
5829  |  |     ret = xmlBase64Decode(input, &inlen, output, &outlen);  | 
5830  |  |  | 
5831  |  |     output[outlen] = 0;  | 
5832  |  |     printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret, inlen, | 
5833  |  |            outlen, output)indent: Standard input:179: Error:Unmatched #endif  | 
5834  |  | ;  | 
5835  |  |  | 
5836  |  |     /*  | 
5837  |  |      * output chunking  | 
5838  |  |      */  | 
5839  |  |     cons = 0;  | 
5840  |  |     prod = 0;  | 
5841  |  |     while (cons < inlen) { | 
5842  |  |         tmp = 5;  | 
5843  |  |         tmp2 = inlen - cons;  | 
5844  |  |  | 
5845  |  |         printf("%ld %ld\n", cons, prod); | 
5846  |  |         ret = xmlBase64Decode(&input[cons], &tmp2, &output2[prod], &tmp);  | 
5847  |  |         cons += tmp2;  | 
5848  |  |         prod += tmp;  | 
5849  |  |         printf("%ld %ld\n", cons, prod); | 
5850  |  |     }  | 
5851  |  |     output2[outlen] = 0;  | 
5852  |  |     printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons, | 
5853  |  |            prod, output2);  | 
5854  |  |  | 
5855  |  |     /*  | 
5856  |  |      * input chunking  | 
5857  |  |      */  | 
5858  |  |     cons = 0;  | 
5859  |  |     prod = 0;  | 
5860  |  |     while (cons < inlen) { | 
5861  |  |         tmp = 100 - prod;  | 
5862  |  |         tmp2 = inlen - cons;  | 
5863  |  |         if (tmp2 > 5)  | 
5864  |  |             tmp2 = 5;  | 
5865  |  |  | 
5866  |  |         printf("%ld %ld\n", cons, prod); | 
5867  |  |         ret = xmlBase64Decode(&input[cons], &tmp2, &output3[prod], &tmp);  | 
5868  |  |         cons += tmp2;  | 
5869  |  |         prod += tmp;  | 
5870  |  |         printf("%ld %ld\n", cons, prod); | 
5871  |  |     }  | 
5872  |  |     output3[outlen] = 0;  | 
5873  |  |     printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons, | 
5874  |  |            prod, output3);  | 
5875  |  |     return (0);  | 
5876  |  |  | 
5877  |  | }  | 
5878  |  | #endif  | 
5879  |  | #endif /* NOT_USED_YET */  | 
5880  |  |  | 
5881  |  | #endif /* LIBXML_READER_ENABLED */  |