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