dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hds / lib / xmlParser.h
1 /**
2  ****************************************************************************
3  * <P> XML.c - implementation file for basic XML parser written in ANSI C++
4  * for portability. It works by using recursion and a node tree for breaking
5  * down the elements of an XML document.  </P>
6  *
7  * @version     V2.23
8  * @author      Frank Vanden Berghen
9  *
10  * BSD license:
11  * Copyright (c) 2002, Frank Vanden Berghen
12  * All rights reserved.
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  *     * Redistributions of source code must retain the above copyright
17  *       notice, this list of conditions and the following disclaimer.
18  *     * Redistributions in binary form must reproduce the above copyright
19  *       notice, this list of conditions and the following disclaimer in the
20  *       documentation and/or other materials provided with the distribution.
21  *     * Neither the name of the Frank Vanden Berghen nor the
22  *       names of its contributors may be used to endorse or promote products
23  *       derived from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
26  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
29  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  ****************************************************************************
37  */
38 #ifndef __INCLUDE_XML_NODE__
39 #define __INCLUDE_XML_NODE__
40
41 #include <stdlib.h>
42
43 #ifdef _UNICODE
44 // If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters).
45 // This is useful when you get error messages like:
46 //    'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *'
47 // The _XMLUNICODE preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable
48 // must be defined) or utf8-mode(the pre-processor variable must be undefined).
49 #define _XMLUNICODE
50 #endif
51
52 #if defined(WIN32) || defined(UNDER_CE)
53 // comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET)
54 #define _XMLWINDOWS
55 #endif
56
57 #ifdef DLLENTRY
58 #undef  DLLENTRY
59 #endif
60 #ifdef _USE_XMLPARSER_DLL
61 #ifdef _DLL_EXPORTS_
62 #define DLLENTRY __declspec(dllexport)
63 #else
64 #define DLLENTRY __declspec(dllimport)
65 #endif
66 #else
67 #define DLLENTRY
68 #endif
69
70 // uncomment the next line if you want no support for wchar_t* (no need for the <wchar.h> or <tchar.h> libraries anymore to compile)
71 //#define XML_NO_WIDE_CHAR
72
73 #ifdef XML_NO_WIDE_CHAR
74 #undef _XMLWINDOWS
75 #undef _XMLUNICODE
76 #endif
77
78 #ifdef _XMLWINDOWS
79 #include <tchar.h>
80 #else
81 #define DLLENTRY
82 #ifndef XML_NO_WIDE_CHAR
83 #include <wchar.h> // to have 'wcsrtombs' for ANSI version
84                    // to have 'mbsrtowcs' for UNICODE version
85 #endif
86 #endif
87
88 // Some common types for char set portable code
89 #ifdef _XMLUNICODE
90     #ifndef _T
91         #define _T(c) L ## c
92     #endif
93     #define XMLCSTR const wchar_t *
94     #define XMLSTR  wchar_t *
95     #define XMLCHAR wchar_t
96 #else
97     #ifndef _T
98         #define _T(c) c
99     #endif
100     #define XMLCSTR const char *
101     #define XMLSTR  char *
102     #define XMLCHAR char
103 #endif
104 #ifndef FALSE
105     #define FALSE 0
106 #endif /* FALSE */
107 #ifndef TRUE
108     #define TRUE 1
109 #endif /* TRUE */
110
111
112 // Enumeration for XML parse errors.
113 typedef enum XMLError
114 {
115     eXMLErrorNone = 0,
116     eXMLErrorMissingEndTag,
117     eXMLErrorEmpty,
118     eXMLErrorFirstNotStartTag,
119     eXMLErrorMissingTagName,
120     eXMLErrorMissingEndTagName,
121     eXMLErrorNoMatchingQuote,
122     eXMLErrorUnmatchedEndTag,
123     eXMLErrorUnmatchedEndClearTag,
124     eXMLErrorUnexpectedToken,
125     eXMLErrorInvalidTag,
126     eXMLErrorNoElements,
127     eXMLErrorFileNotFound,
128     eXMLErrorFirstTagNotFound,
129     eXMLErrorUnknownCharacterEntity,
130     eXMLErrorCharConversionError,
131     eXMLErrorCannotOpenWriteFile,
132     eXMLErrorCannotWriteFile,
133
134     eXMLErrorBase64DataSizeIsNotMultipleOf4,
135     eXMLErrorBase64DecodeIllegalCharacter,
136     eXMLErrorBase64DecodeTruncatedData,
137     eXMLErrorBase64DecodeBufferTooSmall
138 } XMLError;
139
140 // Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
141 typedef enum XMLElementType
142 {
143     eNodeChild=0,
144     eNodeAttribute=1,
145     eNodeText=2,
146     eNodeClear=3,
147     eNodeNULL=4
148 } XMLElementType;
149
150 // Structure used to obtain error details if the parse fails.
151 typedef struct XMLResults
152 {
153     enum XMLError error;
154     int  nLine,nColumn;
155 } XMLResults;
156
157 // Structure for XML clear (unformatted) node (usually comments)
158 typedef struct {
159     XMLCSTR lpszValue; XMLCSTR lpszOpenTag; XMLCSTR lpszCloseTag;
160 } XMLClear;
161
162 // Structure for XML attribute.
163 typedef struct {
164     XMLCSTR lpszName; XMLCSTR lpszValue;
165 } XMLAttribute;
166
167 // Structure for XML clear tags.
168 typedef struct {
169     XMLCSTR lpszOpen; int openTagLen; XMLCSTR lpszClose;
170 } ALLXMLClearTag;
171
172 struct XMLNodeContents;
173
174 typedef struct DLLENTRY XMLNode
175 {
176   private:
177
178     struct XMLNodeDataTag;
179
180     // protected constructors: use one of these four methods to get your first instance of XMLNode:
181     //  - parseString
182     //  - parseFile
183     //  - openFileHelper
184     //  - createXMLTopNode
185     XMLNode(struct XMLNodeDataTag *pParent, XMLCSTR lpszName, char isDeclaration);
186     XMLNode(struct XMLNodeDataTag *p);
187
188   public:
189
190     // You can create your first instance of XMLNode with these 4 functions:
191     // (see complete explanation of parameters below)
192
193     static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE);
194     static XMLNode parseString   (XMLCSTR  lpXMLString, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
195     static XMLNode parseFile     (XMLCSTR     filename, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
196     static XMLNode openFileHelper(XMLCSTR     filename, XMLCSTR tag=NULL                           );
197
198     // The tag parameter should be the name of the first tag inside the XML file.
199     // If the tag parameter is omitted, the 3 functions return a node that represents
200     // the head of the xml document including the declaration term (<? ... ?>).
201
202     // The "openFileHelper" reports to the screen all the warnings & errors that occurred during
203     // parsing of the XML file. Since each application has its own way to report and deal with errors,
204     // you should rather use the "parseFile" function to parse XML files and program yourself thereafter
205     // an "error reporting" tailored for your needs (instead of using the very crude "error reporting"
206     // mechanism included inside the "openFileHelper" function).
207
208     // If the XML document is corrupted:
209     //   * The "openFileHelper" method will:
210     //         - display an error message on the console (or inside a messageBox for windows).
211     //         - stop execution (exit).
212     //     I suggest that you write your own "openFileHelper" method tailored to your needs.
213     //   * The 2 other methods will initialize the "pResults" variable with some information that
214     //     can be used to trace the error.
215     //   * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as
216     //     explained inside the note at the beginning of the "xmlParser.cpp" file.
217     // You can have a user-friendly explanation of the parsing error with this function:
218     static XMLCSTR getError(XMLError error);
219     static XMLCSTR getVersion();
220     static ALLXMLClearTag* getClearTagTable();
221
222     XMLCSTR getName() const;                                         // name of the node
223     XMLCSTR getText(int i=0) const;                                  // return ith text field
224     int nText() const;                                               // nbr of text field
225     XMLNode getParentNode() const;                                   // return the parent node
226     XMLNode getChildNode(int i=0) const;                             // return ith child node
227     XMLNode getChildNode(XMLCSTR name, int i)  const;                // return ith child node with specific name
228                                                                      //     (return an empty node if failing)
229     XMLNode getChildNode(XMLCSTR name, int *i=NULL) const;           // return next child node with specific name
230                                                                      //     (return an empty node if failing)
231     XMLNode getChildNodeWithAttribute(XMLCSTR tagName,               // return child node with specific name/attribute
232                                       XMLCSTR attributeName,         //     (return an empty node if failing)
233                                       XMLCSTR attributeValue=NULL,   //
234                                       int *i=NULL)  const;           //
235     int nChildNode(XMLCSTR name) const;                              // return the number of child node with specific name
236     int nChildNode() const;                                          // nbr of child node
237     XMLAttribute getAttribute(int i=0) const;                        // return ith attribute
238     XMLCSTR      getAttributeName(int i=0) const;                    // return ith attribute name
239     XMLCSTR      getAttributeValue(int i=0) const;                   // return ith attribute value
240     char  isAttributeSet(XMLCSTR name) const;                        // test if an attribute with a specific name is given
241     XMLCSTR getAttribute(XMLCSTR name, int i) const;                 // return ith attribute content with specific name
242                                                                      //     (return a NULL if failing)
243     XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const;           // return next attribute content with specific name
244                                                                      //     (return a NULL if failing)
245     int nAttribute() const;                                          // nbr of attribute
246     XMLClear getClear(int i=0) const;                                // return ith clear field (comments)
247     int nClear() const;                                              // nbr of clear field
248     XMLSTR createXMLString(int nFormat=1, int *pnSize=NULL) const;   // create XML string starting from current XMLNode
249                                                                      // if nFormat==0, no formatting is required
250                                                                      // otherwise this returns an user friendly XML string from a
251                                                                      // given element with appropriate white spaces and carriage returns.
252                                                                      // if pnSize is given it returns the size in character of the string.
253     XMLError writeToFile(XMLCSTR filename, const char *encoding=NULL, char nFormat=1) const;
254                                                                      // save the content of an xmlNode inside a file.
255                                                                      // the nFormat parameter has the same meaning as in the
256                                                                      // createXMLString function. If "strictUTF8Parsing=1", the
257                                                                      // the encoding parameter is ignored and always set to
258                                                                      // "utf-8". If "_XMLUNICODE=1", the encoding parameter is
259                                                                      // ignored and always set to "utf-16".
260     XMLNodeContents enumContents(int i) const;                       // enumerate all the different contents (attribute,child,text,
261                                                                      //     clear) of the current XMLNode. The order is reflecting
262                                                                      //     the order of the original file/string.
263                                                                      //     NOTE: 0 <= i < nElement();
264     int nElement() const;                                            // nbr of different contents for current node
265     char isEmpty() const;                                            // is this node Empty?
266     char isDeclaration() const;                                      // is this node a declaration <? .... ?>
267
268 // to allow shallow/fast copy:
269     ~XMLNode();
270     XMLNode(const XMLNode &A);
271     XMLNode& operator=( const XMLNode& A );
272
273     XMLNode(): d(NULL){};
274     static XMLNode emptyXMLNode;
275     static XMLClear emptyXMLClear;
276     static XMLAttribute emptyXMLAttribute;
277
278     // The following functions allows you to create from scratch (or update) a XMLNode structure
279     // Start by creating your top node with the "createXMLTopNode" function and then add new nodes with the "addChild" function.
280     // The parameter 'pos' gives the position where the childNode, the text or the XMLClearTag will be inserted.
281     // The default value (pos=-1) inserts at the end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end).
282     // REMARK: 0 <= pos < nChild()+nText()+nClear()
283     XMLNode       addChild(XMLCSTR lpszName, char isDeclaration=FALSE, int pos=-1);
284     XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev);
285     XMLCSTR       addText(XMLCSTR lpszValue, int pos=-1);
286     XMLClear     *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, int pos=-1);
287                                                                     // default values: lpszOpen=XMLNode::getClearTagTable()->lpszOpen;
288                                                                     //                 lpszClose=XMLNode::getClearTagTable()->lpszClose;
289     XMLNode       addChild(XMLNode nodeToAdd, int pos=-1);          // If the "nodeToAdd" has some parents, it will be detached
290                                                                     // from it's parents before being attached to the current XMLNode
291     // Some update functions:
292     XMLCSTR       updateName(XMLCSTR lpszName);                                                    // change node's name
293     XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);         // if the attribute to update is missing, a new one will be added
294     XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0);         // if the attribute to update is missing, a new one will be added
295     XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);  // set lpszNewName=NULL if you don't want to change the name of the attribute
296                                                                                                    // if the attribute to update is missing, a new one will be added
297     XMLCSTR       updateText(XMLCSTR lpszNewValue, int i=0);                                       // if the text to update is missing, a new one will be added
298     XMLCSTR       updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                          // if the text to update is missing, a new one will be added
299     XMLClear     *updateClear(XMLCSTR lpszNewContent, int i=0);                                    // if the clearTag to update is missing, a new one will be added
300     XMLClear     *updateClear(XMLClear *newP,XMLClear *oldP);                                      // if the clearTag to update is missing, a new one will be added
301     XMLClear     *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                         // if the clearTag to update is missing, a new one will be added
302
303     // Some deletion functions:
304     void deleteNodeContent(char force=0);  // delete the content of this XMLNode and the subtree.
305                                            // if force=0, while (references to this node still exist), no memory free occurs
306                                            // if force=1, always delete the content of this XMLNode and the subtree and free associated memory
307     void deleteAttribute(XMLCSTR lpszName);
308     void deleteAttribute(int i=0);
309     void deleteAttribute(XMLAttribute *anAttribute);
310     void deleteText(int i=0);
311     void deleteText(XMLCSTR lpszValue);
312     void deleteClear(int i=0);
313     void deleteClear(XMLClear *p);
314     void deleteClear(XMLCSTR lpszValue);
315
316     // The strings given as parameters for the following add and update methods (all these methods have
317     // a name with the postfix "_WOSD" that means "WithOut String Duplication" ) will be free'd by the
318     // XMLNode class. For example, it means that this is incorrect:
319     //    xNode.addText_WOSD("foo");
320     //    xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color");
321     // In opposition, this is correct:
322     //    xNode.addText("foo");
323     //    xNode.addText_WOSD(stringDup("foo"));
324     //    xNode.updateAttribute("#newcolor" ,NULL,"color");
325     //    xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color");
326     // Typically, you will never do:
327     //    char *b=(char*)malloc(...);
328     //    xNode.addText(b);
329     //    free(b);
330     // ... but rather:
331     //    char *b=(char*)malloc(...);
332     //    xNode.addText_WOSD(b);
333     //    ('free(b)' is performed by the XMLNode class)
334
335     static XMLNode createXMLTopNode_WOSD(XMLCSTR lpszName, char isDeclaration=FALSE);
336     XMLNode        addChild_WOSD(XMLCSTR lpszName, char isDeclaration=FALSE, int pos=-1);
337     XMLAttribute  *addAttribute_WOSD(XMLCSTR lpszName, XMLCSTR lpszValue);
338     XMLCSTR        addText_WOSD(XMLCSTR lpszValue, int pos=-1);
339     XMLClear      *addClear_WOSD(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, int pos=-1);
340
341     XMLCSTR        updateName_WOSD(XMLCSTR lpszName);
342     XMLAttribute  *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);
343     XMLAttribute  *updateAttribute_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0);
344     XMLAttribute  *updateAttribute_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);
345     XMLCSTR        updateText_WOSD(XMLCSTR lpszNewValue, int i=0);
346     XMLCSTR        updateText_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);
347     XMLClear      *updateClear_WOSD(XMLCSTR lpszNewContent, int i=0);
348     XMLClear      *updateClear_WOSD(XMLClear *newP,XMLClear *oldP);
349     XMLClear      *updateClear_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);
350
351     // These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the
352     // middle (at a specified position) of a XMLNode tree already constructed. The value returned by these
353     // methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear.
354     int positionOfText(int i=0) const;
355     int positionOfText(XMLCSTR lpszValue) const;
356     int positionOfClear(int i=0) const;
357     int positionOfClear(XMLCSTR lpszValue) const;
358     int positionOfClear(XMLClear *a) const;
359     int positionOfChildNode(int i=0) const;
360     int positionOfChildNode(XMLNode x) const;
361     int positionOfChildNode(XMLCSTR name, int i=0) const; // return the position of the ith childNode with the specified name
362                                                           // if (name==NULL) return the position of the ith childNode
363
364     // The setGlobalOptions function allows you to change two global parameters that affect string&file
365     // parsing. First of all, you most-probably will never have to change these 2 global parameters.
366     // About the "guessUnicodeChars" parameter:
367     //     If "guessUnicodeChars=1" and if this library is compiled in UNICODE mode, then the
368     //     "parseFile" and "openFileHelper" functions will test if the file contains ASCII
369     //     characters. If this is the case, then the file will be loaded and converted in memory to
370     //     UNICODE before being parsed. If "guessUnicodeChars=0", no conversion will
371     //     be performed.
372     //
373     //     If "guessUnicodeChars=1" and if this library is compiled in ASCII/UTF8 mode, then the
374     //     "parseFile" and "openFileHelper" functions will test if the file contains UNICODE
375     //     characters. If this is the case, then the file will be loaded and converted in memory to
376     //     ASCII/UTF8 before being parsed. If "guessUnicodeChars=0", no conversion will
377     //     be performed
378     //
379     //     Sometime, it's useful to set "guessUnicodeChars=0" to disable any conversion
380     //     because the test to detect the file-type (ASCII/UTF8 or UNICODE) may fail (rarely).
381     //
382     // About the "strictUTF8Parsing" parameter:
383     //     If "strictUTF8Parsing=0" then we assume that all characters have the same length of 1 byte.
384     //     If "strictUTF8Parsing=1" then the characters have different lengths (from 1 byte to 4 bytes)
385     //     depending on the content of the first byte of the character.
386     // About the "dropWhiteSpace" parameter:
387     //
388
389     static void setGlobalOptions(char guessUnicodeChars=1, char strictUTF8Parsing=1, char dropWhiteSpace=1);
390
391     // The next function try to guess if the character encoding is UTF-8. You most-probably will never
392     // have to use this function. It then returns the appropriate value of the global parameter
393     // "strictUTF8Parsing" described above. The guess is based on the content of a buffer of length
394     // "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the
395     // file to be parsed. The "openFileHelper" function is using this function to automatically compute
396     // the value of the "strictUTF8Parsing" global parameter. There are several heuristics used to do the
397     // guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications
398     // forbids to use this attribute to do the guess but you can still use it if you set
399     // "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers).
400
401     static char guessUTF8ParsingParameterValue(void *buffer, int bufLen, char useXMLEncodingAttribute=1);
402
403   private:
404
405 // these are functions and structures used internally by the XMLNode class (don't bother about them):
406
407       typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete):
408       {
409           XMLCSTR                lpszName;        // Element name (=NULL if root)
410           int                    nChild,          // Number of child nodes
411                                  nText,           // Number of text fields
412                                  nClear,          // Number of Clear fields (comments)
413                                  nAttribute;      // Number of attributes
414           char                   isDeclaration;   // Whether node is an XML declaration - '<?xml ?>'
415           struct XMLNodeDataTag  *pParent;        // Pointer to parent element (=NULL if root)
416           XMLNode                *pChild;         // Array of child nodes
417           XMLCSTR                *pText;          // Array of text fields
418           XMLClear               *pClear;         // Array of clear fields
419           XMLAttribute           *pAttribute;     // Array of attributes
420           int                    *pOrder;         // order of the child_nodes,text_fields,clear_fields
421           int                    ref_count;       // for garbage collection (smart pointers)
422       } XMLNodeData;
423       XMLNodeData *d;
424
425       char parseClearTag(void *px, ALLXMLClearTag *pa);
426       char maybeAddTxT(void *pa, XMLCSTR tokenPStr);
427       int ParseXMLElement(void *pXML);
428       void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype);
429       int indexText(XMLCSTR lpszValue) const;
430       int indexClear(XMLCSTR lpszValue) const;
431       XMLNode addChild_priv(int,XMLCSTR,char,int);
432       XMLAttribute *addAttribute_priv(int,XMLCSTR,XMLCSTR);
433       XMLCSTR addText_priv(int,XMLCSTR,int);
434       XMLClear *addClear_priv(int,XMLCSTR,XMLCSTR,XMLCSTR,int);
435       static inline int findPosition(XMLNodeData *d, int index, XMLElementType xtype);
436       static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat);
437       static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index);
438       static void exactMemory(XMLNodeData *d);
439       static int detachFromParent(XMLNodeData *d);
440 } XMLNode;
441
442 // This structure is given by the function "enumContents".
443 typedef struct XMLNodeContents
444 {
445     // This dictates what's the content of the XMLNodeContent
446     enum XMLElementType type;
447     // should be an union to access the appropriate data.
448     // compiler does not allow union of object with constructor... too bad.
449     XMLNode child;
450     XMLAttribute attrib;
451     XMLCSTR text;
452     XMLClear clear;
453
454 } XMLNodeContents;
455
456 DLLENTRY void free_XMLDLL(void *t); // {free(t);}
457
458 // Duplicate (copy in a new allocated buffer) the source string. This is
459 // a very handy function when used with all the "XMLNode::*_WOSD" functions.
460 // (If (cbData!=0) then cbData is the number of chars to duplicate)
461 DLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=0);
462
463 // The 3 following functions are processing strings so that all the characters
464 // &,",',<,> are replaced by their XML equivalent: &amp;, &quot;, &apos;, &lt;, &gt;.
465 // These 3 functions are useful when creating from scratch an XML file using the
466 // "printf", "fprintf", "cout",... functions. If you are creating from scratch an
467 // XML file using the provided XMLNode class you cannot use these functions (the
468 // XMLNode class does the processing job for you during rendering). The second
469 // function ("toXMLStringFast") allows you to re-use the same output buffer
470 // for all the conversions so that only a few memory allocations are performed.
471 // If the output buffer is too small to contain thee resulting string, it will
472 // be enlarged.
473 DLLENTRY XMLSTR toXMLString(XMLCSTR source);
474 DLLENTRY XMLSTR toXMLStringFast(XMLSTR *destBuffer,int *destSz, XMLCSTR source);
475
476 // you should not use this one (there is a possibility of "destination-buffer-overflow"):
477 DLLENTRY XMLSTR toXMLString(XMLSTR dest,XMLCSTR source);
478
479 // Below is a class that allows you to include any binary data (images, sounds,...)
480 // into an XML document using "Base64 encoding". This class is completely
481 // separated from the rest of the xmlParser library and can be removed without any problem.
482 // To include some binary data into an XML file, you must convert the binary data into
483 // standard text (using "encode"). To retrieve the original binary data from the
484 // b64-encoded text included inside the XML file use "decode". Alternatively, these
485 // functions can also be used to "encrypt/decrypt" some critical data contained inside
486 // the XML.
487
488 class DLLENTRY XMLParserBase64Tool
489 {
490 public:
491     XMLParserBase64Tool(): buf(NULL),buflen(0){}
492     ~XMLParserBase64Tool();
493
494     void freeBuffer();
495
496     // returns the length of the base64 string that encodes a data buffer of size inBufLen bytes.
497     // If "formatted" parameter is true, some space will be reserved for a carriage-return every 72 chars.
498     static int encodeLength(int inBufLen, char formatted=0);
499
500     // The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes
501     // from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars.
502     // The string will be free'd when the XMLParserBase64Tool object is deleted.
503     // All returned strings are sharing the same memory space.
504     XMLSTR encode(unsigned char *inByteBuf, unsigned int inByteLen, char formatted=0);
505
506     // returns the number of bytes which will be decoded from "inString".
507     static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL);
508
509     // returns a pointer to a buffer containing the binary data decoded from "inString"
510     // If "inString" is malformed NULL will be returned
511     // The output buffer will be free'd when the XMLParserBase64Tool object is deleted.
512     // All output buffer are sharing the same memory space.
513     unsigned char* decode(XMLCSTR inString, int *outByteLen=NULL, XMLError *xe=NULL);
514
515     // The next function is deprecated.
516     // decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf"
517     // in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE"
518     // will be returned; otherwise "TRUE".
519     static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL);
520
521 private:
522     void *buf;
523     int buflen;
524     void alloc(int newsize);
525 };
526
527 #undef  DLLENTRY
528
529 #endif