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