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