[libmusicbrainz4/f18] remove non-free xmlParser.cpp

Tom Callaway spot at fedoraproject.org
Mon Jan 7 18:30:05 UTC 2013


commit adc947cdec1e8270977d88a51d4ea26bc0d05a3c
Author: Tom Callaway <spot at fedoraproject.org>
Date:   Mon Jan 7 13:32:05 2013 -0500

    remove non-free xmlParser.cpp

 libmusicbrainz-4.0.3-xmlparsing.patch | 1370 +++++++++++++++++++++++++++++++++
 libmusicbrainz4.spec                  |   16 +-
 sources                               |    2 +-
 3 files changed, 1385 insertions(+), 3 deletions(-)
---
diff --git a/libmusicbrainz-4.0.3-xmlparsing.patch b/libmusicbrainz-4.0.3-xmlparsing.patch
new file mode 100644
index 0000000..8783d59
--- /dev/null
+++ b/libmusicbrainz-4.0.3-xmlparsing.patch
@@ -0,0 +1,1370 @@
+diff -up libmusicbrainz-4.0.3/CMakeLists.txt.xmlParser libmusicbrainz-4.0.3/CMakeLists.txt
+--- libmusicbrainz-4.0.3/CMakeLists.txt.xmlParser	2012-05-16 15:45:56.000000000 -0400
++++ libmusicbrainz-4.0.3/CMakeLists.txt	2013-01-07 13:13:26.843445449 -0500
+@@ -20,6 +20,7 @@ SET(musicbrainz4_SOVERSION ${musicbrainz
+ 
+ SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
+ FIND_PACKAGE(Neon REQUIRED)
++FIND_PACKAGE(LibXml2 REQUIRED)
+ 
+ SET(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)")
+ SET(EXEC_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "Installation prefix for executables and object code libraries" FORCE)
+diff -up libmusicbrainz-4.0.3/examples/CMakeLists.txt.xmlParser libmusicbrainz-4.0.3/examples/CMakeLists.txt
+--- libmusicbrainz-4.0.3/examples/CMakeLists.txt.xmlParser	2012-05-16 15:45:56.000000000 -0400
++++ libmusicbrainz-4.0.3/examples/CMakeLists.txt	2013-01-07 13:14:03.886460603 -0500
+@@ -1,5 +1,5 @@
+-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include)
+-LINK_LIBRARIES(musicbrainz4 ${NEON_LIBRARIES})
++INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include ${LIBXML2_INCLUDE_DIR})
++LINK_LIBRARIES(musicbrainz4 ${NEON_LIBRARIES} ${LIBXML2_LIBRARIES})
+ 
+ ADD_EXECUTABLE(cdlookup cdlookup.cc)
+ ADD_EXECUTABLE(cdlookup_c cdlookup_c.c)
+diff -up libmusicbrainz-4.0.3/include/musicbrainz4/xmlParser.h.xmlParser libmusicbrainz-4.0.3/include/musicbrainz4/xmlParser.h
+--- libmusicbrainz-4.0.3/include/musicbrainz4/xmlParser.h.xmlParser	2012-05-16 15:45:56.000000000 -0400
++++ libmusicbrainz-4.0.3/include/musicbrainz4/xmlParser.h	2013-01-07 13:13:26.847445453 -0500
+@@ -1,733 +1,111 @@
+-/****************************************************************************/
+-/*! \mainpage XMLParser library
+- * \section intro_sec Introduction
+- *
+- * This is a basic XML parser written in ANSI C++ for portability.
+- * It works by using recursion and a node tree for breaking
+- * down the elements of an XML document.
+- *
+- * @version     V2.43
+- * @author      Frank Vanden Berghen
+- *
+- * Copyright (c) 2002, Business-Insight
+- * <a href="http://www.Business-Insight.com">Business-Insight</a>
+- * All rights reserved.
+- * See the file <a href="../../AFPL-license.txt">AFPL-license.txt</a> about the licensing terms
+- *
+- * \section tutorial First Tutorial
+- * You can follow a simple <a href="../../xmlParser.html">Tutorial</a> to know the basics...
+- *
+- * \section usage General usage: How to include the XMLParser library inside your project.
+- *
+- * The library is composed of two files: <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
+- * <a href="../../xmlParser.h">xmlParser.h</a>. These are the ONLY 2 files that you need when
+- * using the library inside your own projects.
+- *
+- * All the functions of the library are documented inside the comments of the file
+- * <a href="../../xmlParser.h">xmlParser.h</a>. These comments can be transformed in
+- * full-fledged HTML documentation using the DOXYGEN software: simply type: "doxygen doxy.cfg"
+- *
+- * By default, the XMLParser library uses (char*) for string representation.To use the (wchar_t*)
+- * version of the library, you need to define the "_UNICODE" preprocessor definition variable
+- * (this is usually done inside your project definition file) (This is done automatically for you
+- * when using Visual Studio).
+- *
+- * \section example Advanced Tutorial and Many Examples of usage.
+- *
+- * Some very small introductory examples are described inside the Tutorial file
+- * <a href="../../xmlParser.html">xmlParser.html</a>
+- *
+- * Some additional small examples are also inside the file <a href="../../xmlTest.cpp">xmlTest.cpp</a>
+- * (for the "char*" version of the library) and inside the file
+- * <a href="../../xmlTestUnicode.cpp">xmlTestUnicode.cpp</a> (for the "wchar_t*"
+- * version of the library). If you have a question, please review these additionnal examples
+- * before sending an e-mail to the author.
+- *
+- * To build the examples:
+- * - linux/unix: type "make"
+- * - solaris: type "make -f makefile.solaris"
+- * - windows: Visual Studio: double-click on xmlParser.dsw
+- *   (under Visual Studio .NET, the .dsp and .dsw files will be automatically converted to .vcproj and .sln files)
+- *
+- * In order to build the examples you need some additional files:
+- * - linux/unix: makefile
+- * - solaris: makefile.solaris
+- * - windows: Visual Studio: *.dsp, xmlParser.dsw and also xmlParser.lib and xmlParser.dll
+- *
+- * \section debugging Debugging with the XMLParser library
+- *
+- * \subsection debugwin Debugging under WINDOWS
+- *
+- * 	Inside Visual C++, the "debug versions" of the memory allocation functions are
+- * 	very slow: Do not forget to compile in "release mode" to get maximum speed.
+- * 	When I had to debug a software that was using the XMLParser Library, it was usually
+- * 	a nightmare because the library was sooOOOoooo slow in debug mode (because of the
+- *  slow memory allocations in Debug mode). To solve this
+- * 	problem, during all the debugging session, I am now using a very fast DLL version of the
+- * 	XMLParser Library (the DLL is compiled in release mode). Using the DLL version of
+- * 	the XMLParser Library allows me to have lightening XML parsing speed even in debug!
+- * 	Other than that, the DLL version is useless: In the release version of my tool,
+- * 	I always use the normal, ".cpp"-based, XMLParser Library (I simply include the
+- * <a href="../../xmlParser.cpp">xmlParser.cpp</a> and
+- * <a href="../../xmlParser.h">xmlParser.h</a> files into the project).
+- *
+- * 	The file <a href="../../XMLNodeAutoexp.txt">XMLNodeAutoexp.txt</a> contains some
+- * "tweaks" that improve substancially the display of the content of the XMLNode objects
+- * inside the Visual Studio Debugger. Believe me, once you have seen inside the debugger
+- * the "smooth" display of the XMLNode objects, you cannot live without it anymore!
+- *
+- * \subsection debuglinux Debugging under LINUX/UNIX
+- *
+- * 	The speed of the debug version of the XMLParser library is tolerable so no extra
+- * work.has been done.
+- *
+- ****************************************************************************/
+-
+-#ifndef __INCLUDE_XML_NODE__
+-#define __INCLUDE_XML_NODE__
+-
+-#include <stdlib.h>
+-
+-#ifdef _UNICODE
+-// If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters).
+-// This is useful when you get error messages like:
+-//    'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *'
+-// The _XMLWIDECHAR preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable
+-// must be defined) or utf8-mode(the pre-processor variable must be undefined).
+-#define _XMLWIDECHAR
+-#endif
++/* --------------------------------------------------------------------------
+ 
+-#if defined(WIN32) || defined(UNDER_CE) || defined(_WIN32) || defined(WIN64) || defined(__BORLANDC__)
+-// comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET) or Borland
+-#define _XMLWINDOWS
+-#endif
++   libmusicbrainz4 - Client library to access MusicBrainz
+ 
+-#ifdef XMLDLLENTRY
+-#undef XMLDLLENTRY
+-#endif
+-#ifdef _USE_XMLPARSER_DLL
+-#ifdef _DLL_EXPORTS_
+-#define XMLDLLENTRY __declspec(dllexport)
+-#else
+-#define XMLDLLENTRY __declspec(dllimport)
+-#endif
+-#else
+-#define XMLDLLENTRY
+-#endif
++   Copyright (C) 2012 Christophe Fergeau
+ 
+-// 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)
+-//#define XML_NO_WIDE_CHAR
++   This file is part of libmusicbrainz4.
+ 
+-#ifdef XML_NO_WIDE_CHAR
+-#undef _XMLWINDOWS
+-#undef _XMLWIDECHAR
+-#endif
++   This library is free software; you can redistribute it and/or
++   modify it under the terms of v2 of the GNU Lesser General Public
++   License as published by the Free Software Foundation.
+ 
+-#ifdef _XMLWINDOWS
+-#include <tchar.h>
+-#else
+-#define XMLDLLENTRY
+-#ifndef XML_NO_WIDE_CHAR
+-#include <wchar.h> // to have 'wcsrtombs' for ANSI version
+-                   // to have 'mbsrtowcs' for WIDECHAR version
+-#endif
+-#endif
++   libmusicbrainz4 is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
+ 
+-// Some common types for char set portable code
+-#ifdef _XMLWIDECHAR
+-    #define _CXML(c) L ## c
+-    #define XMLCSTR const wchar_t *
+-    #define XMLSTR  wchar_t *
+-    #define XMLCHAR wchar_t
+-#else
+-    #define _CXML(c) c
+-    #define XMLCSTR const char *
+-    #define XMLSTR  char *
+-    #define XMLCHAR char
+-#endif
+-#ifndef FALSE
+-    #define FALSE 0
+-#endif /* FALSE */
+-#ifndef TRUE
+-    #define TRUE 1
+-#endif /* TRUE */
++   You should have received a copy of the GNU General Public License
++   along with this library.  If not, see <http://www.gnu.org/licenses/>.
++
++     $Id$
++
++----------------------------------------------------------------------------*/
++#ifndef _MUSICBRAINZ4_XMLPARSER_H
++#define _MUSICBRAINZ4_XMLPARSER_H
++
++#include <string>
++#include <libxml/tree.h>
++
++typedef xmlError XMLResults;
+ 
++const int eXMLErrorNone = 0;
+ 
+-/// Enumeration for XML parse errors.
+-typedef enum XMLError
++class XMLAttribute;
++class XMLNode
+ {
+-    eXMLErrorNone = 0,
+-    eXMLErrorMissingEndTag,
+-    eXMLErrorNoXMLTagFound,
+-    eXMLErrorEmpty,
+-    eXMLErrorMissingTagName,
+-    eXMLErrorMissingEndTagName,
+-    eXMLErrorUnmatchedEndTag,
+-    eXMLErrorUnmatchedEndClearTag,
+-    eXMLErrorUnexpectedToken,
+-    eXMLErrorNoElements,
+-    eXMLErrorFileNotFound,
+-    eXMLErrorFirstTagNotFound,
+-    eXMLErrorUnknownCharacterEntity,
+-    eXMLErrorCharacterCodeAbove255,
+-    eXMLErrorCharConversionError,
+-    eXMLErrorCannotOpenWriteFile,
+-    eXMLErrorCannotWriteFile,
+-
+-    eXMLErrorBase64DataSizeIsNotMultipleOf4,
+-    eXMLErrorBase64DecodeIllegalCharacter,
+-    eXMLErrorBase64DecodeTruncatedData,
+-    eXMLErrorBase64DecodeBufferTooSmall
+-} XMLError;
++    public:
++        static XMLNode emptyNode();
++        bool isEmpty() const;
+ 
++        virtual ~XMLNode() {};
+ 
+-/// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
+-typedef enum XMLElementType
++        const XMLAttribute getAttribute(const char *name = NULL) const;
++        bool isAttributeSet(const char *name) const;
++
++        XMLNode getChildNode(const char *name = NULL) const;
++        XMLNode next() const;
++        const char *getName() const;
++        const char *getText() const;
++
++        friend bool operator== (const XMLNode &lhs, const XMLNode &rhs);
++
++    protected:
++        XMLNode(xmlNodePtr node): mNode(node) {};
++
++        xmlNodePtr mNode;
++
++    private:
++        xmlAttrPtr getAttributeRaw(const char *name) const;
++};
++
++inline bool operator== (const XMLNode &lhs, const XMLNode &rhs)
+ {
+-    eNodeChild=0,
+-    eNodeAttribute=1,
+-    eNodeText=2,
+-    eNodeClear=3,
+-    eNodeNULL=4
+-} XMLElementType;
++    return (lhs.mNode == rhs.mNode);
++}
+ 
+-/// Structure used to obtain error details if the parse fails.
+-typedef struct XMLResults
++inline bool operator!= (const XMLNode &lhs, const XMLNode &rhs)
+ {
+-    enum XMLError error;
+-    int  nLine,nColumn;
+-} XMLResults;
+-
+-/// Structure for XML clear (unformatted) node (usually comments)
+-typedef struct XMLClear {
+-    XMLCSTR lpszValue; XMLCSTR lpszOpenTag; XMLCSTR lpszCloseTag;
+-} XMLClear;
+-
+-/// Structure for XML attribute.
+-typedef struct XMLAttribute {
+-    XMLCSTR lpszName; XMLCSTR lpszValue;
+-} XMLAttribute;
+-
+-/// XMLElementPosition are not interchangeable with simple indexes
+-typedef int XMLElementPosition;
+-
+-struct XMLNodeContents;
+-
+-/** @defgroup XMLParserGeneral The XML parser */
+-
+-/// Main Class representing a XML node
+-/**
+- * All operations are performed using this class.
+- * \note The constructors of the XMLNode class are protected, so use instead one of these four methods to get your first instance of XMLNode:
+- * <ul>
+- *    <li> XMLNode::parseString </li>
+- *    <li> XMLNode::parseFile </li>
+- *    <li> XMLNode::openFileHelper </li>
+- *    <li> XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)</li>
+- * </ul> */
+-typedef struct XMLDLLENTRY XMLNode
++        return !(lhs == rhs);
++}
++
++class XMLRootNode: public XMLNode
+ {
+-  private:
++    public:
++        static XMLNode* parseString(std::string &xml, XMLResults *results);
++        static XMLNode* parseFile(const std::string &filename, XMLResults *results);
+ 
+-    struct XMLNodeDataTag;
++        virtual ~XMLRootNode() { if (mDoc != NULL) xmlFreeDoc(mDoc); };
+ 
+-    /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
+-    XMLNode(struct XMLNodeDataTag *pParent, XMLSTR lpszName, char isDeclaration);
+-    /// Constructors are protected, so use instead one of: XMLNode::parseString, XMLNode::parseFile, XMLNode::openFileHelper, XMLNode::createXMLTopNode
+-    XMLNode(struct XMLNodeDataTag *p);
+-
+-  public:
+-    static XMLCSTR getVersion();///< Return the XMLParser library version number
+-
+-    /** @defgroup conversions Parsing XML files/strings to an XMLNode structure and Rendering XMLNode's to files/string.
+-     * @ingroup XMLParserGeneral
+-     * @{ */
+-
+-    /// Parse an XML string and return the root of a XMLNode tree representing the string.
+-    static XMLNode parseString   (XMLCSTR  lpXMLString, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
+-    /**< The "parseString" function parse an XML string and return the root of a XMLNode tree. The "opposite" of this function is
+-     * the function "createXMLString" that re-creates an XML string from an XMLNode tree. If the XML document is corrupted, the
+-     * "parseString" method will initialize the "pResults" variable with some information that can be used to trace the error.
+-     * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
+-     * beginning of the "xmlParser.cpp" file.
+-     *
+-     * @param lpXMLString the XML string to parse
+-     * @param tag  the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
+-     * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function.
+-     */
+-
+-    /// Parse an XML file and return the root of a XMLNode tree representing the file.
+-    static XMLNode parseFile     (XMLCSTR     filename, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
+-    /**< The "parseFile" function parse an XML file and return the root of a XMLNode tree. The "opposite" of this function is
+-     * the function "writeToFile" that re-creates an XML file from an XMLNode tree. If the XML document is corrupted, the
+-     * "parseFile" method will initialize the "pResults" variable with some information that can be used to trace the error.
+-     * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the
+-     * beginning of the "xmlParser.cpp" file.
+-     *
+-     * @param filename the path to the XML file to parse
+-     * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
+-     * @param pResults a pointer to a XMLResults variable that will contain some information that can be used to trace the XML parsing error. You can have a user-friendly explanation of the parsing error with the "getError" function.
+-     */
+-
+-    /// Parse an XML file and return the root of a XMLNode tree representing the file. A very crude error checking is made. An attempt to guess the Char Encoding used in the file is made.
+-    static XMLNode openFileHelper(XMLCSTR     filename, XMLCSTR tag=NULL);
+-    /**< The "openFileHelper" function reports to the screen all the warnings and errors that occurred during parsing of the XML file.
+-     * This function also tries to guess char Encoding (UTF-8, ASCII or SHIT-JIS) based on the first 200 bytes of the file. Since each
+-     * application has its own way to report and deal with errors, you should rather use the "parseFile" function to parse XML files
+-     * and program yourself thereafter an "error reporting" tailored for your needs (instead of using the very crude "error reporting"
+-     * mechanism included inside the "openFileHelper" function).
+-     *
+-     * If the XML document is corrupted, the "openFileHelper" method will:
+-     *         - display an error message on the console (or inside a messageBox for windows).
+-     *         - stop execution (exit).
+-     *
+-     * I strongly suggest that you write your own "openFileHelper" method tailored to your needs. If you still want to parse
+-     * the file, you can use the APPROXIMATE_PARSING option as explained inside the note at the beginning of the "xmlParser.cpp" file.
+-     *
+-     * @param filename the path of the XML file to parse.
+-     * @param tag the name of the first tag inside the XML file. If the tag parameter is omitted, this function returns a node that represents the head of the xml document including the declaration term (<? ... ?>).
+-     */
+-
+-    static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error
+-
+-    /// Create an XML string starting from the current XMLNode.
+-    XMLSTR createXMLString(int nFormat=1, int *pnSize=NULL) const;
+-    /**< The returned string should be free'd using the "freeXMLString" function.
+-     *
+-     *   If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element
+-     *   with appropriate white spaces and carriage returns. if pnSize is given it returns the size in character of the string. */
+-
+-    /// Save the content of an xmlNode inside a file
+-    XMLError writeToFile(XMLCSTR filename,
+-                         const char *encoding=NULL,
+-                         char nFormat=1) const;
+-    /**< If nFormat==0, no formatting is required otherwise this returns an user friendly XML string from a given element with appropriate white spaces and carriage returns.
+-     * If the global parameter "characterEncoding==encoding_UTF8", then the "encoding" parameter is ignored and always set to "utf-8".
+-     * If the global parameter "characterEncoding==encoding_ShiftJIS", then the "encoding" parameter is ignored and always set to "SHIFT-JIS".
+-     * If "_XMLWIDECHAR=1", then the "encoding" parameter is ignored and always set to "utf-16".
+-     * If no "encoding" parameter is given the "ISO-8859-1" encoding is used. */
+-    /** @} */
+-
+-    /** @defgroup navigate Navigate the XMLNode structure
+-     * @ingroup XMLParserGeneral
+-     * @{ */
+-    XMLCSTR getName() const;                                       ///< name of the node
+-    XMLCSTR getText(int i=0) const;                                ///< return ith text field
+-    int nText() const;                                             ///< nbr of text field
+-    XMLNode getParentNode() const;                                 ///< return the parent node
+-    XMLNode getChildNode(int i=0) const;                           ///< return ith child node
+-    XMLNode getChildNode(XMLCSTR name, int i)  const;              ///< return ith child node with specific name (return an empty node if failing). If i==-1, this returns the last XMLNode with the given name.
+-    XMLNode getChildNode(XMLCSTR name, int *i=NULL) const;         ///< return next child node with specific name (return an empty node if failing)
+-    XMLNode getChildNodeWithAttribute(XMLCSTR tagName,
+-                                      XMLCSTR attributeName,
+-                                      XMLCSTR attributeValue=NULL,
+-                                      int *i=NULL)  const;         ///< return child node with specific name/attribute (return an empty node if failing)
+-    XMLNode getChildNodeByPath(XMLCSTR path, char createNodeIfMissing=0, XMLCHAR sep='/');
+-                                                                   ///< return the first child node with specific path
+-    XMLNode getChildNodeByPathNonConst(XMLSTR  path, char createNodeIfMissing=0, XMLCHAR sep='/');
+-                                                                   ///< return the first child node with specific path.
+-
+-    int nChildNode(XMLCSTR name) const;                            ///< return the number of child node with specific name
+-    int nChildNode() const;                                        ///< nbr of child node
+-    XMLAttribute getAttribute(int i=0) const;                      ///< return ith attribute
+-    XMLCSTR      getAttributeName(int i=0) const;                  ///< return ith attribute name
+-    XMLCSTR      getAttributeValue(int i=0) const;                 ///< return ith attribute value
+-    char  isAttributeSet(XMLCSTR name) const;                      ///< test if an attribute with a specific name is given
+-    XMLCSTR getAttribute(XMLCSTR name, int i) const;               ///< return ith attribute content with specific name (return a NULL if failing)
+-    XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const;         ///< return next attribute content with specific name (return a NULL if failing)
+-    int nAttribute() const;                                        ///< nbr of attribute
+-    XMLClear getClear(int i=0) const;                              ///< return ith clear field (comments)
+-    int nClear() const;                                            ///< nbr of clear field
+-    XMLNodeContents enumContents(XMLElementPosition i) const;      ///< enumerate all the different contents (attribute,child,text, clear) of the current XMLNode. The order is reflecting the order of the original file/string. NOTE: 0 <= i < nElement();
+-    int nElement() const;                                          ///< nbr of different contents for current node
+-    char isEmpty() const;                                          ///< is this node Empty?
+-    char isDeclaration() const;                                    ///< is this node a declaration <? .... ?>
+-    XMLNode deepCopy() const;                                      ///< deep copy (duplicate/clone) a XMLNode
+-    static XMLNode emptyNode();                                    ///< return XMLNode::emptyXMLNode;
+-    /** @} */
+-
+-    ~XMLNode();
+-    XMLNode(const XMLNode &A);                                     ///< to allow shallow/fast copy:
+-    XMLNode& operator=( const XMLNode& A );                        ///< to allow shallow/fast copy:
+-
+-    XMLNode(): d(NULL){};
+-    static XMLNode emptyXMLNode;
+-    static XMLClear emptyXMLClear;
+-    static XMLAttribute emptyXMLAttribute;
+-
+-    /** @defgroup xmlModify Create or Update the XMLNode structure
+-     * @ingroup XMLParserGeneral
+-     *  The functions in this group allows you to create from scratch (or update) a XMLNode structure. Start by creating your top
+-     *  node with the "createXMLTopNode" function and then add new nodes with the "addChild" function. The parameter 'pos' gives
+-     *  the position where the childNode, the text or the XMLClearTag will be inserted. 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). <br>
+-     *
+-     *  REMARK: 0 <= pos < nChild()+nText()+nClear() <br>
+-     */
+-
+-    /** @defgroup creation Creating from scratch a XMLNode structure
+-     * @ingroup xmlModify
+-     * @{ */
+-    static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE);                    ///< Create the top node of an XMLNode structure
+-    XMLNode        addChild(XMLCSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1); ///< Add a new child node
+-    XMLNode        addChild(XMLNode nodeToAdd, XMLElementPosition pos=-1);                          ///< If the "nodeToAdd" has some parents, it will be detached from it's parents before being attached to the current XMLNode
+-    XMLAttribute  *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev);                              ///< Add a new attribute
+-    XMLCSTR        addText(XMLCSTR lpszValue, XMLElementPosition pos=-1);                           ///< Add a new text content
+-    XMLClear      *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1);
+-    /**< Add a new clear tag
+-     * @param lpszOpen default value "<![CDATA["
+-     * @param lpszClose default value "]]>"
+-     */
+-    /** @} */
+-
+-    /** @defgroup xmlUpdate Updating Nodes
+-     * @ingroup xmlModify
+-     * Some update functions:
+-     * @{
+-     */
+-    XMLCSTR       updateName(XMLCSTR lpszName);                                                  ///< change node's name
+-    XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);       ///< if the attribute to update is missing, a new one will be added
+-    XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0);       ///< if the attribute to update is missing, a new one will be added
+-    XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added
+-    XMLCSTR       updateText(XMLCSTR lpszNewValue, int i=0);                                     ///< if the text to update is missing, a new one will be added
+-    XMLCSTR       updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                        ///< if the text to update is missing, a new one will be added
+-    XMLClear     *updateClear(XMLCSTR lpszNewContent, int i=0);                                  ///< if the clearTag to update is missing, a new one will be added
+-    XMLClear     *updateClear(XMLClear *newP,XMLClear *oldP);                                    ///< if the clearTag to update is missing, a new one will be added
+-    XMLClear     *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                       ///< if the clearTag to update is missing, a new one will be added
+-    /** @} */
+-
+-    /** @defgroup xmlDelete Deleting Nodes or Attributes
+-     * @ingroup xmlModify
+-     * Some deletion functions:
+-     * @{
+-     */
+-    /// The "deleteNodeContent" function forces the deletion of the content of this XMLNode and the subtree.
+-    void deleteNodeContent();
+-    /**< \note The XMLNode instances that are referring to the part of the subtree that has been deleted CANNOT be used anymore!!. Unexpected results will occur if you continue using them. */
+-    void deleteAttribute(int i=0);                   ///< Delete the ith attribute of the current XMLNode
+-    void deleteAttribute(XMLCSTR lpszName);          ///< Delete the attribute with the given name (the "strcmp" function is used to find the right attribute)
+-    void deleteAttribute(XMLAttribute *anAttribute); ///< Delete the attribute with the name "anAttribute->lpszName" (the "strcmp" function is used to find the right attribute)
+-    void deleteText(int i=0);                        ///< Delete the Ith text content of the current XMLNode
+-    void deleteText(XMLCSTR lpszValue);              ///< Delete the text content "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the right text)
+-    void deleteClear(int i=0);                       ///< Delete the Ith clear tag inside the current XMLNode
+-    void deleteClear(XMLCSTR lpszValue);             ///< Delete the clear tag "lpszValue" inside the current XMLNode (direct "pointer-to-pointer" comparison is used to find the clear tag)
+-    void deleteClear(XMLClear *p);                   ///< Delete the clear tag "p" inside the current XMLNode (direct "pointer-to-pointer" comparison on the lpszName of the clear tag is used to find the clear tag)
+-    /** @} */
+-
+-    /** @defgroup xmlWOSD ???_WOSD functions.
+-     * @ingroup xmlModify
+-     *  The strings given as parameters for the "add" and "update" methods that have a name with
+-     *  the postfix "_WOSD" (that means "WithOut String Duplication")(for example "addText_WOSD")
+-     *  will be free'd by the XMLNode class. For example, it means that this is incorrect:
+-     *  \code
+-     *     xNode.addText_WOSD("foo");
+-     *     xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color");
+-     *  \endcode
+-     *  In opposition, this is correct:
+-     *  \code
+-     *     xNode.addText("foo");
+-     *     xNode.addText_WOSD(stringDup("foo"));
+-     *     xNode.updateAttribute("#newcolor" ,NULL,"color");
+-     *     xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color");
+-     *  \endcode
+-     *  Typically, you will never do:
+-     *  \code
+-     *     char *b=(char*)malloc(...);
+-     *     xNode.addText(b);
+-     *     free(b);
+-     *  \endcode
+-     *  ... but rather:
+-     *  \code
+-     *     char *b=(char*)malloc(...);
+-     *     xNode.addText_WOSD(b);
+-     *  \endcode
+-     *  ('free(b)' is performed by the XMLNode class)
+-     * @{ */
+-    static XMLNode createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration=FALSE);                     ///< Create the top node of an XMLNode structure
+-    XMLNode        addChild_WOSD(XMLSTR lpszName, char isDeclaration=FALSE, XMLElementPosition pos=-1);  ///< Add a new child node
+-    XMLAttribute  *addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValue);                                 ///< Add a new attribute
+-    XMLCSTR        addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos=-1);                            ///< Add a new text content
+-    XMLClear      *addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, XMLElementPosition pos=-1); ///< Add a new clear Tag
+-
+-    XMLCSTR        updateName_WOSD(XMLSTR lpszName);                                                  ///< change node's name
+-    XMLAttribute  *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);      ///< if the attribute to update is missing, a new one will be added
+-    XMLAttribute  *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName=NULL,int i=0);        ///< if the attribute to update is missing, a new one will be added
+-    XMLAttribute  *updateAttribute_WOSD(XMLSTR lpszNewValue, XMLSTR lpszNewName,XMLCSTR lpszOldName); ///< set lpszNewName=NULL if you don't want to change the name of the attribute if the attribute to update is missing, a new one will be added
+-    XMLCSTR        updateText_WOSD(XMLSTR lpszNewValue, int i=0);                                     ///< if the text to update is missing, a new one will be added
+-    XMLCSTR        updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue);                        ///< if the text to update is missing, a new one will be added
+-    XMLClear      *updateClear_WOSD(XMLSTR lpszNewContent, int i=0);                                  ///< if the clearTag to update is missing, a new one will be added
+-    XMLClear      *updateClear_WOSD(XMLClear *newP,XMLClear *oldP);                                   ///< if the clearTag to update is missing, a new one will be added
+-    XMLClear      *updateClear_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue);                       ///< if the clearTag to update is missing, a new one will be added
+-    /** @} */
+-
+-    /** @defgroup xmlPosition Position helper functions (use in conjunction with the update&add functions
+-     * @ingroup xmlModify
+-     * These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the
+-     * middle (at a specified position) of a XMLNode tree already constructed. The value returned by these
+-     * methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear.
+-     * @{ */
+-    XMLElementPosition positionOfText(int i=0) const;
+-    XMLElementPosition positionOfText(XMLCSTR lpszValue) const;
+-    XMLElementPosition positionOfClear(int i=0) const;
+-    XMLElementPosition positionOfClear(XMLCSTR lpszValue) const;
+-    XMLElementPosition positionOfClear(XMLClear *a) const;
+-    XMLElementPosition positionOfChildNode(int i=0) const;
+-    XMLElementPosition positionOfChildNode(XMLNode x) const;
+-    XMLElementPosition positionOfChildNode(XMLCSTR name, int i=0) const; ///< return the position of the ith childNode with the specified name if (name==NULL) return the position of the ith childNode
+-    /** @} */
+-
+-    /// Enumeration for XML character encoding.
+-    typedef enum XMLCharEncoding
+-    {
+-        char_encoding_error=0,
+-        char_encoding_UTF8=1,
+-        char_encoding_legacy=2,
+-        char_encoding_ShiftJIS=3,
+-        char_encoding_GB2312=4,
+-        char_encoding_Big5=5,
+-        char_encoding_GBK=6     // this is actually the same as Big5
+-    } XMLCharEncoding;
+-
+-    /** \addtogroup conversions
+-     * @{ */
+-
+-    /// Sets the global options for the conversions
+-    static char setGlobalOptions(XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8, char guessWideCharChars=1,
+-                                 char dropWhiteSpace=1, char removeCommentsInMiddleOfText=1);
+-    /**< The "setGlobalOptions" function allows you to change four global parameters that affect string & file
+-     * parsing. First of all, you most-probably will never have to change these 3 global parameters.
+-     *
+-     * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in WideChar mode, then the
+-     *     XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains ASCII
+-     *     characters. If this is the case, then the file will be loaded and converted in memory to
+-     *     WideChar before being parsed. If 0, no conversion will be performed.
+-     *
+-     * @param guessWideCharChars If "guessWideCharChars"=1 and if this library is compiled in ASCII/UTF8/char* mode, then the
+-     *     XMLNode::parseFile and XMLNode::openFileHelper functions will test if the file contains WideChar
+-     *     characters. If this is the case, then the file will be loaded and converted in memory to
+-     *     ASCII/UTF8/char* before being parsed. If 0, no conversion will be performed.
+-     *
+-     * @param characterEncoding This parameter is only meaningful when compiling in char* mode (multibyte character mode).
+-     *     In wchar_t* (wide char mode), this parameter is ignored. This parameter should be one of the
+-     *     three currently recognized encodings: XMLNode::encoding_UTF8, XMLNode::encoding_ascii,
+-     *     XMLNode::encoding_ShiftJIS.
+-     *
+-     * @param dropWhiteSpace In most situations, text fields containing only white spaces (and carriage returns)
+-     *     are useless. Even more, these "empty" text fields are annoying because they increase the
+-     *     complexity of the user's code for parsing. So, 99% of the time, it's better to drop
+-     *     the "empty" text fields. However The XML specification indicates that no white spaces
+-     *     should be lost when parsing the file. So to be perfectly XML-compliant, you should set
+-     *     dropWhiteSpace=0. A note of caution: if you set "dropWhiteSpace=0", the parser will be
+-     *     slower and your code will be more complex.
+-     *
+-     * @param removeCommentsInMiddleOfText To explain this parameter, let's consider this code:
+-     * \code
+-     *        XMLNode x=XMLNode::parseString("<a>foo<!-- hello -->bar<!DOCTYPE world >chu</a>","a");
+-     * \endcode
+-     *     If removeCommentsInMiddleOfText=0, then we will have:
+-     * \code
+-     *        x.getText(0) -> "foo"
+-     *        x.getText(1) -> "bar"
+-     *        x.getText(2) -> "chu"
+-     *        x.getClear(0) --> "<!-- hello -->"
+-     *        x.getClear(1) --> "<!DOCTYPE world >"
+-     * \endcode
+-     *     If removeCommentsInMiddleOfText=1, then we will have:
+-     * \code
+-     *        x.getText(0) -> "foobar"
+-     *        x.getText(1) -> "chu"
+-     *        x.getClear(0) --> "<!DOCTYPE world >"
+-     * \endcode
+-     *
+-     * \return "0" when there are no errors. If you try to set an unrecognized encoding then the return value will be "1" to signal an error.
+-     *
+-     * \note Sometime, it's useful to set "guessWideCharChars=0" to disable any conversion
+-     * because the test to detect the file-type (ASCII/UTF8/char* or WideChar) may fail (rarely). */
+-
+-    /// Guess the character encoding of the string (ascii, utf8 or shift-JIS)
+-    static XMLCharEncoding guessCharEncoding(void *buffer, int bufLen, char useXMLEncodingAttribute=1);
+-    /**< The "guessCharEncoding" function try to guess the character encoding. You most-probably will never
+-     * have to use this function. It then returns the appropriate value of the global parameter
+-     * "characterEncoding" described in the XMLNode::setGlobalOptions. The guess is based on the content of a buffer of length
+-     * "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the
+-     * file to be parsed. The XMLNode::openFileHelper function is using this function to automatically compute
+-     * the value of the "characterEncoding" global parameter. There are several heuristics used to do the
+-     * guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications
+-     * forbids to use this attribute to do the guess but you can still use it if you set
+-     * "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers).
+-     * If an inconsistency in the encoding is detected, then the return value is "0". */
+-    /** @} */
+-
+-  private:
+-      // these are functions and structures used internally by the XMLNode class (don't bother about them):
+-
+-      typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete):
+-      {
+-          XMLCSTR                lpszName;        // Element name (=NULL if root)
+-          int                    nChild,          // Number of child nodes
+-                                 nText,           // Number of text fields
+-                                 nClear,          // Number of Clear fields (comments)
+-                                 nAttribute;      // Number of attributes
+-          char                   isDeclaration;   // Whether node is an XML declaration - '<?xml ?>'
+-          struct XMLNodeDataTag  *pParent;        // Pointer to parent element (=NULL if root)
+-          XMLNode                *pChild;         // Array of child nodes
+-          XMLCSTR                *pText;          // Array of text fields
+-          XMLClear               *pClear;         // Array of clear fields
+-          XMLAttribute           *pAttribute;     // Array of attributes
+-          int                    *pOrder;         // order of the child_nodes,text_fields,clear_fields
+-          int                    ref_count;       // for garbage collection (smart pointers)
+-      } XMLNodeData;
+-      XMLNodeData *d;
+-
+-      char parseClearTag(void *px, void *pa);
+-      char maybeAddTxT(void *pa, XMLCSTR tokenPStr);
+-      int ParseXMLElement(void *pXML);
+-      void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype);
+-      int indexText(XMLCSTR lpszValue) const;
+-      int indexClear(XMLCSTR lpszValue) const;
+-      XMLNode addChild_priv(int,XMLSTR,char,int);
+-      XMLAttribute *addAttribute_priv(int,XMLSTR,XMLSTR);
+-      XMLCSTR addText_priv(int,XMLSTR,int);
+-      XMLClear *addClear_priv(int,XMLSTR,XMLCSTR,XMLCSTR,int);
+-      void emptyTheNode(char force);
+-      static inline XMLElementPosition findPosition(XMLNodeData *d, int index, XMLElementType xtype);
+-      static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat);
+-      static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index);
+-      static void exactMemory(XMLNodeData *d);
+-      static int detachFromParent(XMLNodeData *d);
+-} XMLNode;
++    private:
++        XMLRootNode(xmlDocPtr doc);
+ 
+-/// This structure is given by the function XMLNode::enumContents.
+-typedef struct XMLNodeContents
+-{
+-    /// This dictates what's the content of the XMLNodeContent
+-    enum XMLElementType etype;
+-    /**< should be an union to access the appropriate data. Compiler does not allow union of object with constructor... too bad. */
+-    XMLNode child;
+-    XMLAttribute attrib;
+-    XMLCSTR text;
+-    XMLClear clear;
+-
+-} XMLNodeContents;
+-
+-/** @defgroup StringAlloc String Allocation/Free functions
+- * @ingroup xmlModify
+- * @{ */
+-/// Duplicate (copy in a new allocated buffer) the source string.
+-XMLDLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=-1);
+-/**< This is
+- * a very handy function when used with all the "XMLNode::*_WOSD" functions (\link xmlWOSD \endlink).
+- * @param cbData If !=0 then cbData is the number of chars to duplicate. New strings allocated with
+- * this function should be free'd using the "freeXMLString" function. */
+-
+-/// to free the string allocated inside the "stringDup" function or the "createXMLString" function.
+-XMLDLLENTRY void freeXMLString(XMLSTR t); // {free(t);}
+-/** @} */
+-
+-/** @defgroup atoX ato? like functions
+- * @ingroup XMLParserGeneral
+- * The "xmlto?" functions are equivalents to the atoi, atol, atof functions.
+- * The only difference is: If the variable "xmlString" is NULL, than the return value
+- * is "defautValue". These 6 functions are only here as "convenience" functions for the
+- * user (they are not used inside the XMLparser). If you don't need them, you can
+- * delete them without any trouble.
+- *
+- * @{ */
+-XMLDLLENTRY char    xmltob(XMLCSTR xmlString,char   defautValue=0);
+-XMLDLLENTRY int     xmltoi(XMLCSTR xmlString,int    defautValue=0);
+-XMLDLLENTRY long    xmltol(XMLCSTR xmlString,long   defautValue=0);
+-XMLDLLENTRY double  xmltof(XMLCSTR xmlString,double defautValue=.0);
+-XMLDLLENTRY XMLCSTR xmltoa(XMLCSTR xmlString,XMLCSTR defautValue=_CXML(""));
+-XMLDLLENTRY XMLCHAR xmltoc(XMLCSTR xmlString,const XMLCHAR defautValue=_CXML('\0'));
+-/** @} */
+-
+-/** @defgroup ToXMLStringTool Helper class to create XML files using "printf", "fprintf", "cout",... functions.
+- * @ingroup XMLParserGeneral
+- * @{ */
+-/// Helper class to create XML files using "printf", "fprintf", "cout",... functions.
+-/** The ToXMLStringTool class helps you creating XML files using "printf", "fprintf", "cout",... functions.
+- * The "ToXMLStringTool" class is processing strings so that all the characters
+- * &,",',<,> are replaced by their XML equivalent:
+- * \verbatim &amp;, &quot;, &apos;, &lt;, &gt; \endverbatim
+- * Using the "ToXMLStringTool class" and the "fprintf function" is THE most efficient
+- * way to produce VERY large XML documents VERY fast.
+- * \note If you are creating from scratch an XML file using the provided XMLNode class
+- * you must not use the "ToXMLStringTool" class (because the "XMLNode" class does the
+- * processing job for you during rendering).*/
+-typedef struct XMLDLLENTRY ToXMLStringTool
+-{
+-public:
+-    ToXMLStringTool(): buf(NULL),buflen(0){}
+-    ~ToXMLStringTool();
+-    void freeBuffer();///<call this function when you have finished using this object to release memory used by the internal buffer.
+-
+-    XMLSTR toXML(XMLCSTR source);///< returns a pointer to an internal buffer that contains a XML-encoded string based on the "source" parameter.
+-
+-    /** The "toXMLUnSafe" function is deprecated because there is a possibility of
+-     * "destination-buffer-overflow". It converts the string
+-     * "source" to the string "dest". */
+-    static XMLSTR toXMLUnSafe(XMLSTR dest,XMLCSTR source); ///< deprecated: use "toXML" instead
+-    static int lengthXMLString(XMLCSTR source);            ///< deprecated: use "toXML" instead
+-
+-private:
+-    XMLSTR buf;
+-    int buflen;
+-} ToXMLStringTool;
+-/** @} */
+-
+-/** @defgroup XMLParserBase64Tool Helper class to include binary data inside XML strings using "Base64 encoding".
+- * @ingroup XMLParserGeneral
+- * @{ */
+-/// Helper class to include binary data inside XML strings using "Base64 encoding".
+-/** The "XMLParserBase64Tool" class allows you to include any binary data (images, sounds,...)
+- * into an XML document using "Base64 encoding". This class is completely
+- * separated from the rest of the xmlParser library and can be removed without any problem.
+- * To include some binary data into an XML file, you must convert the binary data into
+- * standard text (using "encode"). To retrieve the original binary data from the
+- * b64-encoded text included inside the XML file, use "decode". Alternatively, these
+- * functions can also be used to "encrypt/decrypt" some critical data contained inside
+- * the XML (it's not a strong encryption at all, but sometimes it can be useful). */
+-typedef struct XMLDLLENTRY XMLParserBase64Tool
++        mutable xmlDocPtr mDoc;
++};
++
++class XMLAttribute
+ {
+-public:
+-    XMLParserBase64Tool(): buf(NULL),buflen(0){}
+-    ~XMLParserBase64Tool();
+-    void freeBuffer();///< Call this function when you have finished using this object to release memory used by the internal buffer.
+-
+-    /**
+-     * @param formatted If "formatted"=true, some space will be reserved for a carriage-return every 72 chars. */
+-    static int encodeLength(int inBufLen, char formatted=0); ///< return the length of the base64 string that encodes a data buffer of size inBufLen bytes.
+-
+-    /**
+-     * The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes
+-     * from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars.
+-     * The string will be free'd when the XMLParserBase64Tool object is deleted.
+-     * All returned strings are sharing the same memory space. */
+-    XMLSTR encode(unsigned char *inByteBuf, unsigned int inByteLen, char formatted=0); ///< returns a pointer to an internal buffer containing the base64 string containing the binary data encoded from "inByteBuf"
+-
+-    /// returns the number of bytes which will be decoded from "inString".
+-    static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL);
+-
+-    /**
+-     * The "decode" function returns a pointer to a buffer containing the binary data decoded from "inString"
+-     * The output buffer will be free'd when the XMLParserBase64Tool object is deleted.
+-     * All output buffer are sharing the same memory space.
+-     * @param inString If "instring" is malformed, NULL will be returned */
+-    unsigned char* decode(XMLCSTR inString, int *outByteLen=NULL, XMLError *xe=NULL); ///< returns a pointer to an internal buffer containing the binary data decoded from "inString"
+-
+-    /**
+-     * decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf"
+-     * in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE"
+-     * will be returned; otherwise "TRUE". */
+-    static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL); ///< deprecated.
+-
+-private:
+-    void *buf;
+-    int buflen;
+-    void alloc(int newsize);
+-}XMLParserBase64Tool;
+-/** @} */
++    public:
++        bool isEmpty() const {
++            return (mAttr == NULL);
++        }
++
++        std::string name() const {
++            return std::string((const char *)mAttr->name);
++        }
++
++        std::string value() const {
++            return std::string((const char *)mAttr->children->content);
++        }
++        const XMLAttribute next() const {
++            return XMLAttribute(mAttr->next);
++        }
++
++        friend const XMLAttribute XMLNode::getAttribute(const char *name) const;
+ 
+-#undef XMLDLLENTRY
++    private:
++        XMLAttribute(xmlAttrPtr attr): mAttr(attr) {};
++        xmlAttrPtr mAttr;
++};
+ 
+ #endif
+diff -up libmusicbrainz-4.0.3/libmusicbrainz4.pc.cmake.xmlParser libmusicbrainz-4.0.3/libmusicbrainz4.pc.cmake
+--- libmusicbrainz-4.0.3/libmusicbrainz4.pc.cmake.xmlParser	2012-05-16 15:45:56.000000000 -0400
++++ libmusicbrainz-4.0.3/libmusicbrainz4.pc.cmake	2013-01-07 13:14:38.306473041 -0500
+@@ -8,6 +8,6 @@ Description: The Musicbrainz Client Libr
+ URL: http://musicbrainz.org/doc/libmusicbrainz
+ Version: ${PROJECT_VERSION}
+ Requires.private: neon >= 0.25
++Requires: libxml-2.0
+ Libs: -L${LIB_INSTALL_DIR} -lmusicbrainz4
+ Cflags: -I${INCLUDE_INSTALL_DIR}
+-
+diff -up libmusicbrainz-4.0.3/src/cinterface.xml.xmlParser libmusicbrainz-4.0.3/src/cinterface.xml
+--- libmusicbrainz-4.0.3/src/cinterface.xml.xmlParser	2012-05-16 15:45:56.000000000 -0400
++++ libmusicbrainz-4.0.3/src/cinterface.xml	2013-01-07 13:14:55.940480936 -0500
+@@ -1,5 +1,4 @@
+ <!--
+- --------------------------------------------------------------------------
+ 
+    libmusicbrainz4 - Client library to access MusicBrainz
+ 
+@@ -21,7 +20,6 @@
+ 
+      $Id$
+ 
+-----------------------------------------------------------------------------
+ -->
+ 
+ <cinterface>
+@@ -218,7 +216,7 @@ extern "C"
+ 		<property name="artist" type="string"/>
+ 		<property name="length" type="integer"/>
+ 	</class>
+-	<class name="puid" uppername="PUID" uppername="PUID">
++	<class name="puid" uppername="PUID">
+ 		<property name="id" uppername="ID" type="string"/>
+ 		<property name="recordinglist" uppername="RecordingList" type="object"/>
+ 	</class>
+diff -up libmusicbrainz-4.0.3/src/CMakeLists.txt.xmlParser libmusicbrainz-4.0.3/src/CMakeLists.txt
+--- libmusicbrainz-4.0.3/src/CMakeLists.txt.xmlParser	2012-05-16 15:45:56.000000000 -0400
++++ libmusicbrainz-4.0.3/src/CMakeLists.txt	2013-01-07 13:16:36.014528553 -0500
+@@ -1,14 +1,15 @@
+ SET(CMAKE_INCLUDE_CURRENT_DIR ON)
+-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/../include ${NEON_INCLUDE_DIR})
++INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/../include ${NEON_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
+ 
+ SET(_sources Alias.cc Annotation.cc Artist.cc ArtistCredit.cc Attribute.cc CDStub.cc Collection.cc
+ 	Disc.cc Entity.cc FreeDBDisc.cc HTTPFetch.cc ISRC.cc Label.cc LabelInfo.cc Lifespan.cc List.cc
+ 	mb4_c.cc Medium.cc MediumList.cc Message.cc Metadata.cc NameCredit.cc NonMBTrack.cc PUID.cc
+ 	Query.cc Rating.cc Recording.cc Relation.cc RelationList.cc Release.cc ReleaseGroup.cc Tag.cc
+-	TextRepresentation.cc Track.cc UserRating.cc UserTag.cc Work.cc xmlParser.cpp
++	TextRepresentation.cc Track.cc UserRating.cc UserTag.cc Work.cc xmlParser.cc
+ 	RelationListList.cc ISWCList.cc ISWC.cc SecondaryType.cc SecondaryTypeList.cc IPI.cc)
+ 
+-ADD_EXECUTABLE(make-c-interface make-c-interface.cc xmlParser.cpp)
++ADD_EXECUTABLE(make-c-interface make-c-interface.cc xmlParser.cc)
++TARGET_LINK_LIBRARIES(make-c-interface ${LIBXML2_LIBRARIES})
+ 
+ ADD_CUSTOM_COMMAND(
+ 	OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mb4_c.cc ${CMAKE_CURRENT_BINARY_DIR}/mb4_c.h ${CMAKE_CURRENT_BINARY_DIR}/../include/musicbrainz4/mb4_c.h
+@@ -36,7 +37,7 @@ if(CMAKE_BUILD_TYPE STREQUAL Debug)
+ 	ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+ endif(CMAKE_BUILD_TYPE STREQUAL Debug)
+ 
+-TARGET_LINK_LIBRARIES(musicbrainz4 ${NEON_LIBRARIES})
++TARGET_LINK_LIBRARIES(musicbrainz4 ${NEON_LIBRARIES} ${LIBXML2_LIBRARIES})
+ 
+ IF(WIN32)
+     TARGET_LINK_LIBRARIES(musicbrainz4 wsock32 winmm ws2_32)
+@@ -47,7 +48,7 @@ IF(CMAKE_COMPILER_IS_GNUCXX)
+ 		IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../.git)
+ 			SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
+ 		ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../.git)
+-		set_source_files_properties(mb4_c.cc PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations")
++		#set_source_files_properties(mb4_c.cc PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations")
+ ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+ 
+ INSTALL(TARGETS musicbrainz4 DESTINATION ${LIB_INSTALL_DIR})
+diff -up libmusicbrainz-4.0.3/src/Entity.cc.xmlParser libmusicbrainz-4.0.3/src/Entity.cc
+--- libmusicbrainz-4.0.3/src/Entity.cc.xmlParser	2012-05-16 15:45:56.000000000 -0400
++++ libmusicbrainz-4.0.3/src/Entity.cc	2013-01-07 13:13:26.849445455 -0500
+@@ -80,10 +80,12 @@ void MusicBrainz4::CEntity::Parse(const
+ {
+ 	if (!Node.isEmpty())
+ 	{
+-		for (int count=0;count<Node.nAttribute();count++)
++		for (XMLAttribute Attr = Node.getAttribute();
++		    !Attr.isEmpty();
++		    Attr = Attr.next())
+ 		{
+-			std::string Name=Node.getAttributeName(count);
+-			std::string Value=Node.getAttributeValue(count);
++			std::string Name=Attr.name();
++			std::string Value=Attr.value();
+ 
+ 			if ("ext:"==Name.substr(0,4))
+ 				m_d->m_ExtAttributes[Name.substr(4)]=Value;
+@@ -93,10 +95,10 @@ void MusicBrainz4::CEntity::Parse(const
+ 
+ 		//std::cout << "Node: " << std::endl << Node.createXMLString(true) << std::endl;
+ 
+-		for (int count=0;count<Node.nChildNode();count++)
++		for (XMLNode ChildNode = Node.getChildNode();
++		     !ChildNode.isEmpty();
++		     ChildNode = ChildNode.next())
+ 		{
+-			XMLNode ChildNode=Node.getChildNode(count);
+-
+ 			std::string Name=ChildNode.getName();
+ 			std::string Value;
+ 			if (ChildNode.getText())
+diff -up libmusicbrainz-4.0.3/src/make-c-interface.cc.xmlParser libmusicbrainz-4.0.3/src/make-c-interface.cc
+--- libmusicbrainz-4.0.3/src/make-c-interface.cc.xmlParser	2012-05-16 15:45:56.000000000 -0400
++++ libmusicbrainz-4.0.3/src/make-c-interface.cc	2013-01-07 13:19:33.055611671 -0500
+@@ -28,6 +28,7 @@
+ #include <iostream>
+ #include <fstream>
+ #include <sstream>
++#include <unistd.h>
+ #include <vector>
+ #include <string>
+ 
+@@ -51,8 +52,8 @@ int main(int argc, const char *argv[])
+ 	{
+ 		std::string XMLFile=std::string(argv[1])+"/"+argv[2];
+ 		XMLResults Results;
+-		XMLNode TopNode=XMLNode::parseFile(XMLFile.c_str(),"cinterface",&Results);
+-		if (!TopNode.isEmpty())
++		XMLNode *TopNode=XMLRootNode::parseFile(XMLFile.c_str(),&Results);
++		if (!TopNode->isEmpty())
+ 		{
+ 			std::cout << "Generating '" << argv[3] << "/" << argv[4] << "' and '" << argv[3] << "/" << argv[5] << "'" << std::endl;
+ 
+@@ -74,9 +75,10 @@ int main(int argc, const char *argv[])
+ 				return 1;
+ 			}
+ 
+-			for (int count=0;count<TopNode.nChildNode();count++)
++			for (XMLNode Node = TopNode->getChildNode();
++			     !Node.isEmpty();
++			     Node = Node.next())
+ 			{
+-				XMLNode Node=TopNode.getChildNode(count);
+ 				std::string Name=Node.getName();
+ 
+ 				if ("boilerplate"==Name)
+@@ -84,7 +86,7 @@ int main(int argc, const char *argv[])
+ 				else if ("header"==Name)
+ 					ProcessHeader(Node,Source,Include);
+ 				else if ("declare"==Name)
+-					ProcessDeclare(TopNode,Source,Include);
++					ProcessDeclare(*TopNode,Source,Include);
+ 				else if ("entity"==Name)
+ 					ProcessEntity(Node,Source,Include);
+ 				else if ("class"==Name)
+@@ -100,9 +102,11 @@ int main(int argc, const char *argv[])
+ 		}
+ 		else
+ 		{
+-			std::cerr << "Error reading XML: " << XMLNode::getError(Results.error) << " at line " << Results.nLine << std::endl;
++			std::cerr << "Error reading XML: " << Results.message << " at line " << Results.line << std::endl;
+ 			return 1;
+ 		}
++                if (TopNode != NULL)
++                    delete TopNode;
+ 	}
+ 
+ 	return 0;
+@@ -114,7 +118,7 @@ std::ofstream *GetFile(const XMLNode& No
+ 
+ 	if (Node.isAttributeSet("target"))
+ 	{
+-		std::string Target=Node.getAttribute("target");
++		std::string Target=Node.getAttribute("target").value();
+ 		if ("source"==Target)
+ 			File=&Source;
+ 		else if ("include"==Target)
+@@ -162,7 +166,7 @@ void ProcessBoilerplate(const XMLNode& N
+ 
+ 	if (Node.isAttributeSet("file"))
+ 	{
+-		std::string FileName=Node.getAttribute("file");
++		std::string FileName=Node.getAttribute("file").value();
+ 		std::ifstream InFile(FileName.c_str());
+ 		if (InFile.is_open())
+ 			*File << InFile.rdbuf() << std::endl;
+@@ -263,11 +267,11 @@ void ProcessClass(const XMLNode& Node, s
+ {
+ 	if (Node.isAttributeSet("name"))
+ 	{
+-		std::string LowerName=Node.getAttribute("name");
++		std::string LowerName=Node.getAttribute("name").value();
+ 
+ 		std::string UpperName=LowerName;
+ 		if (Node.isAttributeSet("uppername"))
+-			UpperName=Node.getAttribute("uppername");
++			UpperName=Node.getAttribute("uppername").value();
+ 		else
+ 			UpperName[0]=toupper(UpperName[0]);
+ 
+@@ -294,24 +298,25 @@ void ProcessClass(const XMLNode& Node, s
+ 
+ 		Source << "  MB4_C_CLONE(" << UpperName << "," << LowerName << ")" << std::endl;
+ 
+-		for (int count=0;count<Node.nChildNode();count++)
++		for (XMLNode ChildNode = Node.getChildNode();
++                     !ChildNode.isEmpty();
++                     ChildNode = ChildNode.next())
+ 		{
+-			XMLNode ChildNode=Node.getChildNode(count);
+ 			std::string Name=ChildNode.getName();
+ 
+ 			if ("property"==Name)
+ 			{
+ 				if (ChildNode.isAttributeSet("name") && ChildNode.isAttributeSet("type"))
+ 				{
+-					std::string PropertyLowerName=ChildNode.getAttribute("name");
++					std::string PropertyLowerName=ChildNode.getAttribute("name").value();
+ 
+ 					std::string PropertyUpperName=PropertyLowerName;
+ 					if (ChildNode.isAttributeSet("uppername"))
+-						PropertyUpperName=ChildNode.getAttribute("uppername");
++						PropertyUpperName=ChildNode.getAttribute("uppername").value();
+ 					else
+ 						PropertyUpperName[0]=toupper(PropertyUpperName[0]);
+ 
+-					std::string PropertyType=ChildNode.getAttribute("type");
++					std::string PropertyType=ChildNode.getAttribute("type").value();
+ 
+ 					if ("string"==PropertyType)
+ 					{
+@@ -320,13 +325,13 @@ void ProcessClass(const XMLNode& Node, s
+ 
+ 						if (ChildNode.isAttributeSet("deprecated"))
+ 						{
+-							std::string StrDeprecated=ChildNode.getAttribute("deprecated");
++							std::string StrDeprecated=ChildNode.getAttribute("deprecated").value();
+ 
+ 							if (StrDeprecated=="true")
+ 								Deprecated=true;
+ 
+ 							if (ChildNode.isAttributeSet("replacement"))
+-								Replacement=ChildNode.getAttribute("replacement");
++								Replacement=ChildNode.getAttribute("replacement").value();
+ 						}
+ 
+ 						Include << "/**" << std::endl;
+@@ -516,11 +521,11 @@ void ProcessList(const XMLNode& Node, st
+ {
+ 	if (Node.isAttributeSet("name"))
+ 	{
+-		std::string LowerName=Node.getAttribute("name");
++		std::string LowerName=Node.getAttribute("name").value();
+ 
+ 		std::string UpperName=LowerName;
+ 		if (Node.isAttributeSet("uppername"))
+-			UpperName=Node.getAttribute("uppername");
++			UpperName=Node.getAttribute("uppername").value();
+ 		else
+ 			UpperName[0]=toupper(UpperName[0]);
+ 
+@@ -578,24 +583,25 @@ void ProcessList(const XMLNode& Node, st
+ 
+ 		Source << "  MB4_C_CLONE(" << UpperName << "List," << LowerName << "_list)" << std::endl;
+ 
+-		for (int count=0;count<Node.nChildNode();count++)
++		for (XMLNode ChildNode = Node.getChildNode();
++                     !ChildNode.isEmpty();
++                     ChildNode = ChildNode.next())
+ 		{
+-			XMLNode ChildNode=Node.getChildNode(count);
+ 			std::string Name=ChildNode.getName();
+ 
+ 			if ("property"==Name)
+ 			{
+ 				if (ChildNode.isAttributeSet("name") && ChildNode.isAttributeSet("type"))
+ 				{
+-					std::string PropertyLowerName=ChildNode.getAttribute("name");
++					std::string PropertyLowerName=ChildNode.getAttribute("name").value();
+ 
+ 					std::string PropertyUpperName=PropertyLowerName;
+ 					if (ChildNode.isAttributeSet("uppername"))
+-						PropertyUpperName=ChildNode.getAttribute("uppername");
++						PropertyUpperName=ChildNode.getAttribute("uppername").value();
+ 					else
+ 						PropertyUpperName[0]=toupper(PropertyUpperName[0]);
+ 
+-					std::string PropertyType=ChildNode.getAttribute("type");
++					std::string PropertyType=ChildNode.getAttribute("type").value();
+ 
+ 					if ("string"==PropertyType)
+ 					{
+@@ -683,18 +689,19 @@ void ProcessDeclare(const XMLNode& Node,
+ 	std::vector<std::string> Classes;
+ 	Classes.push_back("Entity");
+ 
+-	for (int count=0;count<Node.nChildNode();count++)
++	for (XMLNode ChildNode = Node.getChildNode();
++	     !ChildNode.isEmpty();
++	     ChildNode = ChildNode.next())
+ 	{
+-		XMLNode ChildNode=Node.getChildNode(count);
+ 		std::string Name=ChildNode.getName();
+ 
+ 		if ("class"==Name || "list"==Name)
+ 		{
+ 			if (ChildNode.isAttributeSet("name"))
+ 			{
+-				std::string UpperName=ChildNode.getAttribute("name");
++				std::string UpperName=ChildNode.getAttribute("name").value();
+ 				if (ChildNode.isAttributeSet("uppername"))
+-					UpperName=ChildNode.getAttribute("uppername");
++					UpperName=ChildNode.getAttribute("uppername").value();
+ 				else
+ 					UpperName[0]=toupper(UpperName[0]);
+ 
+diff -up libmusicbrainz-4.0.3/src/Query.cc.xmlParser libmusicbrainz-4.0.3/src/Query.cc
+--- libmusicbrainz-4.0.3/src/Query.cc.xmlParser	2012-05-16 15:45:56.000000000 -0400
++++ libmusicbrainz-4.0.3/src/Query.cc	2013-01-07 13:13:26.850445456 -0500
+@@ -158,15 +158,16 @@ MusicBrainz4::CMetadata MusicBrainz4::CQ
+ #endif
+ 
+ 			XMLResults Results;
+-			XMLNode TopNode=XMLNode::parseString(strData.c_str(), 0, &Results);
+-			if (Results.error==eXMLErrorNone)
++			XMLNode *TopNode = XMLRootNode::parseString(strData, &Results);
++			if (Results.code==eXMLErrorNone)
+ 			{
+-				XMLNode MetadataNode=TopNode.getChildNode("metadata");
++				XMLNode MetadataNode=*TopNode;
+ 				if (!MetadataNode.isEmpty())
+ 				{
+ 					Metadata=CMetadata(MetadataNode);
+ 				}
+ 			}
++			delete TopNode;
+ 		}
+ 	}
+ 
+@@ -393,10 +394,10 @@ bool MusicBrainz4::CQuery::EditCollectio
+ #endif
+ 
+ 				XMLResults Results;
+-				XMLNode TopNode=XMLNode::parseString(strData.c_str(), 0, &Results);
+-				if (Results.error==eXMLErrorNone)
++				XMLNode *TopNode = XMLRootNode::parseString(strData, &Results);
++				if (Results.code==eXMLErrorNone)
+ 				{
+-					XMLNode MetadataNode=TopNode.getChildNode("metadata");
++					XMLNode MetadataNode=*TopNode;
+ 					if (!MetadataNode.isEmpty())
+ 					{
+ 						CMetadata Metadata(MetadataNode);
+@@ -405,6 +406,7 @@ bool MusicBrainz4::CQuery::EditCollectio
+ 							RetVal=RetVal && true;
+ 					}
+ 				}
++				delete TopNode;
+ 			}
+ 		}
+ 
+diff -up libmusicbrainz-4.0.3/src/xmlParser.cc.xmlParser libmusicbrainz-4.0.3/src/xmlParser.cc
+--- libmusicbrainz-4.0.3/src/xmlParser.cc.xmlParser	2013-01-07 13:13:26.850445456 -0500
++++ libmusicbrainz-4.0.3/src/xmlParser.cc	2013-01-07 13:13:26.850445456 -0500
+@@ -0,0 +1,147 @@
++/* --------------------------------------------------------------------------
++
++   libmusicbrainz4 - Client library to access MusicBrainz
++
++   Copyright (C) 2012 Christophe Fergeau
++
++   This file is part of libmusicbrainz4.
++
++   This library is free software; you can redistribute it and/or
++   modify it under the terms of v2 of the GNU Lesser General Public
++   License as published by the Free Software Foundation.
++
++   libmusicbrainz4 is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this library.  If not, see <http://www.gnu.org/licenses/>.
++
++     $Id$
++
++----------------------------------------------------------------------------*/
++
++#include "config.h"
++#include "musicbrainz4/defines.h"
++
++#include "musicbrainz4/xmlParser.h"
++
++#include <cstring>
++
++XMLNode XMLNode::emptyNode()
++{
++    return XMLNode(NULL);
++}
++
++XMLNode *XMLRootNode::parseFile(const std::string &filename, xmlErrorPtr results)
++{
++    xmlDocPtr doc;
++
++    doc = xmlParseFile(filename.c_str());
++    if ((doc == NULL) && (results != NULL)) {
++        xmlCopyError(xmlGetLastError(), results);
++    }
++
++    return new XMLRootNode(doc);
++}
++
++XMLNode *XMLRootNode::parseString(std::string &xml, xmlErrorPtr results)
++{
++    xmlDocPtr doc;
++
++    doc = xmlParseMemory(xml.c_str(), xml.length());
++    if ((doc == NULL) && (results != NULL)) {
++        xmlCopyError(xmlGetLastError(), results);
++    }
++
++    return new XMLRootNode(doc);
++}
++
++const char *XMLNode::getName() const
++{
++    return (char *)mNode->name;
++}
++
++const char *XMLNode::getText() const
++{
++    if (mNode->children == NULL)
++        return NULL;
++    if (!xmlNodeIsText(mNode->children))
++        return NULL;
++
++    return (char*)mNode->children->content;
++}
++
++xmlAttrPtr XMLNode::getAttributeRaw(const char *name) const
++{
++    xmlAttrPtr attr;
++
++    for (attr = mNode->properties; attr != NULL; attr = attr->next)
++        if (strcmp(name, (char *)attr->name) == 0)
++            return attr;
++
++    return NULL;
++}
++
++const XMLAttribute XMLNode::getAttribute(const char *name) const
++{
++    xmlAttrPtr attr;
++
++    if (name == NULL)
++        return XMLAttribute(mNode->properties);
++
++    attr = this->getAttributeRaw(name);
++    if (attr != NULL)
++        return XMLAttribute(attr);
++
++    return XMLAttribute(NULL);
++}
++
++bool XMLNode::isAttributeSet(const char *name) const
++{
++    return (this->getAttributeRaw(name) != NULL);
++}
++
++XMLRootNode::XMLRootNode(xmlDocPtr doc): XMLNode(xmlDocGetRootElement(doc)),
++                                         mDoc(doc)
++{
++}
++
++static xmlNodePtr skipTextNodes(xmlNodePtr node)
++{
++    xmlNodePtr it = node;
++
++    while ((it != NULL) && xmlNodeIsText(it))
++        it = it->next;
++
++    return it;
++}
++
++XMLNode XMLNode::next() const
++{
++    return XMLNode(skipTextNodes(mNode->next));
++}
++
++XMLNode XMLNode::getChildNode(const char *name) const
++{
++    xmlNodePtr it;
++    if (name == NULL)
++        return XMLNode(skipTextNodes(mNode->children));
++
++    for (it = mNode->children; it != NULL; it = it->next) {
++        if (xmlNodeIsText(it))
++            continue;
++        if (strcmp(name, (char *)it->name) == 0)
++            return XMLNode(it);
++    }
++
++    return emptyNode();
++}
++
++bool XMLNode::isEmpty() const
++{
++    return mNode == NULL;
++}
++
++
+diff -up libmusicbrainz-4.0.3/tests/CMakeLists.txt.xmlParser libmusicbrainz-4.0.3/tests/CMakeLists.txt
+--- libmusicbrainz-4.0.3/tests/CMakeLists.txt.xmlParser	2012-05-16 15:45:56.000000000 -0400
++++ libmusicbrainz-4.0.3/tests/CMakeLists.txt	2013-01-07 13:22:58.578705974 -0500
+@@ -1,5 +1,5 @@
+-INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include)
+-LINK_LIBRARIES(musicbrainz4 ${NEON_LIBRARIES})
++INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include ${LIBXML2_INCLUDE_DIR})
++LINK_LIBRARIES(musicbrainz4 ${NEON_LIBRARIES} ${LIBXML2_LIBRARIES})
+ ADD_EXECUTABLE(mbtest mbtest.cc)
+ ADD_EXECUTABLE(ctest ctest.c)
+ 
diff --git a/libmusicbrainz4.spec b/libmusicbrainz4.spec
index fe59dad..289da7d 100644
--- a/libmusicbrainz4.spec
+++ b/libmusicbrainz4.spec
@@ -4,16 +4,24 @@
 Summary: Library for accessing MusicBrainz servers
 Name: libmusicbrainz4
 Version: 4.0.3
-Release: 2%{?dist}
+Release: 3%{?dist}
 License: LGPLv2+
 Group: System Environment/Libraries
 URL: http://www.musicbrainz.org/
-Source0: ftp://ftp.musicbrainz.org/pub/musicbrainz/libmusicbrainz-%{version}.tar.gz
+# Source0: ftp://ftp.musicbrainz.org/pub/musicbrainz/libmusicbrainz-%{version}.tar.gz
+# We need to remove src/xmlParser.cpp, as it is non-free and prohibits commercial distribution.
+# Just unpack and rm -rf src/xmlParser.cpp, then
+# tar cfz libmusicbrainz-%{version}-clean.tar.gz libmusicbrainz-%{version}/
+Source0: libmusicbrainz-%{version}-clean.tar.gz
+# This patch replaces the removed src/xmlParser.cpp support with libxml2
+# and fixes up the cinterface.xml file (libxml2 seems to be stricter).
+Patch0: libmusicbrainz-4.0.3-xmlparsing.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 BuildRequires: cmake
 BuildRequires: doxygen
 BuildRequires: neon-devel
+BuildRequires: libxml2-devel
 BuildRequires: pkgconfig
 
 %description
@@ -32,6 +40,7 @@ applications which will use %{name}.
 
 %prep
 %setup -q -n libmusicbrainz-%{version}
+%patch0 -p1 -b .xmlParser
 
 # omit "Generated on ..." timestamps that induce multilib conflicts
 # this is *supposed* to be the doxygen default in fedora these days, but
@@ -77,6 +86,9 @@ rm -rf %{buildroot}
 
 
 %changelog
+* Mon Jan  7 2013 Tom Callaway <spot at fedoraproject.org> - 4.0.3-3
+- remove non-free xmlParser.cpp
+
 * Thu Jul 19 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 4.0.3-2
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
 
diff --git a/sources b/sources
index f3e80a6..4fc64d6 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-19b43a543d338751e9dc524f6236892b  libmusicbrainz-4.0.3.tar.gz
+fa793423fbcfaea2779a019657539d00  libmusicbrainz-4.0.3-clean.tar.gz


More information about the scm-commits mailing list