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