Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/AI/src/xml/xmlParser.h @ 233

Last change on this file since 233 was 164, checked in by nicolasc, 17 years ago

Brute force megre of xml branch

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