diff --git a/.gitignore b/.gitignore
index 78502e1..a8d6716 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
/libmusicbrainz-5.0.1.tar.gz
/libmusicbrainz-5.0.1-clean.tar.gz
+/libmusicbrainz-5.1.0.tar.gz
diff --git a/0001-xmlparsing.patch b/0001-xmlparsing.patch
deleted file mode 100644
index 0cadff4..0000000
--- a/0001-xmlparsing.patch
+++ /dev/null
@@ -1,1374 +0,0 @@
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 16870b4..a1f5a65 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -20,6 +20,7 @@ SET(musicbrainz5_SOVERSION ${musicbrainz5_SOVERSION_MAJOR})
-
- 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 --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
-index 3e11469..440d4f2 100644
---- a/examples/CMakeLists.txt
-+++ b/examples/CMakeLists.txt
-@@ -1,5 +1,5 @@
--INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include)
--LINK_LIBRARIES(musicbrainz5 ${NEON_LIBRARIES})
-+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include ${LIBXML2_INCLUDE_DIR})
-+LINK_LIBRARIES(musicbrainz5 ${NEON_LIBRARIES} ${LIBXML2_LIBRARIES})
-
- ADD_EXECUTABLE(cdlookup cdlookup.cc)
- ADD_EXECUTABLE(cdlookup_c cdlookup_c.c)
-diff --git a/include/musicbrainz5/xmlParser.h b/include/musicbrainz5/xmlParser.h
-index 56b29d7..45db5fc 100644
---- a/include/musicbrainz5/xmlParser.h
-+++ b/include/musicbrainz5/xmlParser.h
-@@ -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
-- * Business-Insight
-- * All rights reserved.
-- * See the file AFPL-license.txt about the licensing terms
-- *
-- * \section tutorial First Tutorial
-- * You can follow a simple Tutorial to know the basics...
-- *
-- * \section usage General usage: How to include the XMLParser library inside your project.
-- *
-- * The library is composed of two files: xmlParser.cpp and
-- * xmlParser.h. 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
-- * xmlParser.h. 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
-- * xmlParser.html
-- *
-- * Some additional small examples are also inside the file xmlTest.cpp
-- * (for the "char*" version of the library) and inside the file
-- * xmlTestUnicode.cpp (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
-- * xmlParser.cpp and
-- * xmlParser.h files into the project).
-- *
-- * The file XMLNodeAutoexp.txt 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__
-+ libmusicbrainz5 - Client library to access MusicBrainz
-
--#include
-+ Copyright (C) 2012 Christophe Fergeau
-
--#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
--
--#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
-+ This file is part of libmusicbrainz5.
-
--// uncomment the next line if you want no support for wchar_t* (no need for the or libraries anymore to compile)
--//#define XML_NO_WIDE_CHAR
-+ 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 XML_NO_WIDE_CHAR
--#undef _XMLWINDOWS
--#undef _XMLWIDECHAR
--#endif
-+ libmusicbrainz5 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.
-
--#ifdef _XMLWINDOWS
--#include
--#else
--#define XMLDLLENTRY
--#ifndef XML_NO_WIDE_CHAR
--#include // to have 'wcsrtombs' for ANSI version
-- // to have 'mbsrtowcs' for WIDECHAR version
--#endif
--#endif
-+ You should have received a copy of the GNU General Public License
-+ along with this library. If not, see .
-
--// 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 */
-+ $Id$
-
-+----------------------------------------------------------------------------*/
-+#ifndef _MUSICBRAINZ5_XMLPARSER_H
-+#define _MUSICBRAINZ5_XMLPARSER_H
-
--/// Enumeration for XML parse errors.
--typedef enum XMLError
--{
-- eXMLErrorNone = 0,
-- eXMLErrorMissingEndTag,
-- eXMLErrorNoXMLTagFound,
-- eXMLErrorEmpty,
-- eXMLErrorMissingTagName,
-- eXMLErrorMissingEndTagName,
-- eXMLErrorUnmatchedEndTag,
-- eXMLErrorUnmatchedEndClearTag,
-- eXMLErrorUnexpectedToken,
-- eXMLErrorNoElements,
-- eXMLErrorFileNotFound,
-- eXMLErrorFirstTagNotFound,
-- eXMLErrorUnknownCharacterEntity,
-- eXMLErrorCharacterCodeAbove255,
-- eXMLErrorCharConversionError,
-- eXMLErrorCannotOpenWriteFile,
-- eXMLErrorCannotWriteFile,
--
-- eXMLErrorBase64DataSizeIsNotMultipleOf4,
-- eXMLErrorBase64DecodeIllegalCharacter,
-- eXMLErrorBase64DecodeTruncatedData,
-- eXMLErrorBase64DecodeBufferTooSmall
--} XMLError;
-+#include
-+#include
-
-+typedef xmlError XMLResults;
-
--/// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
--typedef enum XMLElementType
--{
-- eNodeChild=0,
-- eNodeAttribute=1,
-- eNodeText=2,
-- eNodeClear=3,
-- eNodeNULL=4
--} XMLElementType;
-+const int eXMLErrorNone = 0;
-
--/// Structure used to obtain error details if the parse fails.
--typedef struct XMLResults
-+class XMLAttribute;
-+class XMLNode
- {
-- 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:
-- *
-- * - XMLNode::parseString
-- * - XMLNode::parseFile
-- * - XMLNode::openFileHelper
-- * - XMLNode::createXMLTopNode (or XMLNode::createXMLTopNode_WOSD)
-- *
*/
--typedef struct XMLDLLENTRY XMLNode
--{
-- private:
--
-- struct XMLNodeDataTag;
--
-- /// 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.
-- */
-+ public:
-+ static XMLNode emptyNode();
-+ bool isEmpty() const;
-
-- /// 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 ( ... ?>).
-- */
-+ virtual ~XMLNode() {};
-
-- static XMLCSTR getError(XMLError error); ///< this gives you a user-friendly explanation of the parsing error
-+ const XMLAttribute getAttribute(const char *name = NULL) const;
-+ bool isAttributeSet(const char *name) const;
-
-- /// 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. */
-+ XMLNode getChildNode(const char *name = NULL) const;
-+ XMLNode next() const;
-+ const char *getName() const;
-+ const char *getText() const;
-
-- /// 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. */
-- /** @} */
-+ friend bool operator== (const XMLNode &lhs, const XMLNode &rhs);
-
-- /** @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.
-+ protected:
-+ XMLNode(xmlNodePtr node): mNode(node) {};
-
-- 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;
-- /** @} */
-+ xmlNodePtr mNode;
-
-- ~XMLNode();
-- XMLNode(const XMLNode &A); ///< to allow shallow/fast copy:
-- XMLNode& operator=( const XMLNode& A ); ///< to allow shallow/fast copy:
-+ private:
-+ xmlAttrPtr getAttributeRaw(const char *name) const;
-+};
-
-- 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).
-- *
-- * REMARK: 0 <= pos < nChild()+nText()+nClear()
-- */
--
-- /** @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 ""
-- */
-- /** @} */
--
-- /** @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("foobarchu","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) --> ""
-- * x.getClear(1) --> ""
-- * \endcode
-- * If removeCommentsInMiddleOfText=1, then we will have:
-- * \code
-- * x.getText(0) -> "foobar"
-- * x.getText(1) -> "chu"
-- * x.getClear(0) --> ""
-- * \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 - ''
-- 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;
--
--/// This structure is given by the function XMLNode::enumContents.
--typedef struct XMLNodeContents
-+inline bool operator== (const XMLNode &lhs, const XMLNode &rhs)
- {
-- /// 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. */
-+ return (lhs.mNode == rhs.mNode);
-+}
-
--/// 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 &, ", ', <, > \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
-+inline bool operator!= (const XMLNode &lhs, const XMLNode &rhs)
- {
--public:
-- ToXMLStringTool(): buf(NULL),buflen(0){}
-- ~ToXMLStringTool();
-- void freeBuffer();///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;
-+
-+ private:
-+ XMLAttribute(xmlAttrPtr attr): mAttr(attr) {};
-+ xmlAttrPtr mAttr;
-+};
-
- #endif
-diff --git a/libmusicbrainz5.pc.cmake b/libmusicbrainz5.pc.cmake
-index c2f45c9..fca0de1 100644
---- a/libmusicbrainz5.pc.cmake
-+++ b/libmusicbrainz5.pc.cmake
-@@ -8,6 +8,7 @@ Description: The Musicbrainz Client Library.
- URL: http://musicbrainz.org/doc/libmusicbrainz
- Version: ${PROJECT_VERSION}
- Requires.private: neon >= 0.25
-+Requires: libxml-2.0
- Libs: -L${LIB_INSTALL_DIR} -lmusicbrainz5
- Cflags: -I${INCLUDE_INSTALL_DIR}
-
-diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
-index 2ee102f..368dd93 100644
---- a/src/CMakeLists.txt
-+++ b/src/CMakeLists.txt
-@@ -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
- mb5_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}/mb5_c.cc ${CMAKE_CURRENT_BINARY_DIR}/mb5_c.h ${CMAKE_CURRENT_BINARY_DIR}/../include/musicbrainz5/mb5_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(musicbrainz5 ${NEON_LIBRARIES})
-+TARGET_LINK_LIBRARIES(musicbrainz5 ${NEON_LIBRARIES} ${LIBXML2_LIBRARIES})
-
- IF(WIN32)
- TARGET_LINK_LIBRARIES(musicbrainz5 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(mb5_c.cc PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations")
-+ #set_source_files_properties(mb5_c.cc PROPERTIES COMPILE_FLAGS "-Wno-deprecated-declarations")
- ENDIF(CMAKE_COMPILER_IS_GNUCXX)
-
- INSTALL(TARGETS musicbrainz5 DESTINATION ${LIB_INSTALL_DIR})
-diff --git a/src/Entity.cc b/src/Entity.cc
-index 0644377..a1bb1ca 100644
---- a/src/Entity.cc
-+++ b/src/Entity.cc
-@@ -80,10 +80,12 @@ void MusicBrainz5::CEntity::Parse(const XMLNode& Node)
- {
- if (!Node.isEmpty())
- {
-- for (int count=0;countm_ExtAttributes[Name.substr(4)]=Value;
-@@ -93,10 +95,10 @@ void MusicBrainz5::CEntity::Parse(const XMLNode& Node)
-
- //std::cout << "Node: " << std::endl << Node.createXMLString(true) << std::endl;
-
-- for (int count=0;count
-
-
-@@ -218,7 +216,7 @@ extern "C"
-
-
-
--
-+
-
-
-
-diff --git a/src/make-c-interface.cc b/src/make-c-interface.cc
-index 652a65b..97af3d9 100644
---- a/src/make-c-interface.cc
-+++ b/src/make-c-interface.cc
-@@ -28,6 +28,8 @@
- #include
- #include
- #include
-+#include
-+#include
- #include
- #include
-
-@@ -51,8 +53,9 @@ 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);
-+ memset(&Results, 0, sizeof(Results));
-+ if (!TopNode->isEmpty())
- {
- std::cout << "Generating '" << argv[3] << "/" << argv[4] << "' and '" << argv[3] << "/" << argv[5] << "'" << std::endl;
-
-@@ -74,9 +77,10 @@ int main(int argc, const char *argv[])
- return 1;
- }
-
-- for (int count=0;countgetChildNode();
-+ !Node.isEmpty();
-+ Node = Node.next())
- {
-- XMLNode Node=TopNode.getChildNode(count);
- std::string Name=Node.getName();
-
- if ("boilerplate"==Name)
-@@ -84,7 +88,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 +104,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 +120,7 @@ std::ofstream *GetFile(const XMLNode& Node, std::ofstream& Source, std::ofstream
-
- 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 +168,7 @@ void ProcessBoilerplate(const XMLNode& Node, std::ofstream& Source, std::ofstrea
-
- 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 +269,11 @@ void ProcessClass(const XMLNode& Node, std::ofstream& Source, std::ofstream& Inc
- {
- 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 +300,25 @@ void ProcessClass(const XMLNode& Node, std::ofstream& Source, std::ofstream& Inc
-
- Source << " MB5_C_CLONE(" << UpperName << "," << LowerName << ")" << std::endl;
-
-- for (int count=0;count Classes;
- Classes.push_back("Entity");
-
-- for (int count=0;count.
-+
-+ $Id$
-+
-+----------------------------------------------------------------------------*/
-+
-+#include "config.h"
-+#include "musicbrainz5/defines.h"
-+
-+#include "musicbrainz5/xmlParser.h"
-+
-+#include
-+
-+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 --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
-index 645f8ae..8dd569c 100644
---- a/tests/CMakeLists.txt
-+++ b/tests/CMakeLists.txt
-@@ -1,5 +1,5 @@
--INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include)
--LINK_LIBRARIES(musicbrainz5 ${NEON_LIBRARIES})
-+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include ${LIBXML2_INCLUDE_DIR})
-+LINK_LIBRARIES(musicbrainz5 ${NEON_LIBRARIES} ${LIBXML2_LIBRARIES})
- ADD_EXECUTABLE(mbtest mbtest.cc)
- ADD_EXECUTABLE(ctest ctest.c)
-
diff --git a/libmusicbrainz5.spec b/libmusicbrainz5.spec
index aa12991..6948125 100644
--- a/libmusicbrainz5.spec
+++ b/libmusicbrainz5.spec
@@ -3,25 +3,18 @@
Summary: Library for accessing MusicBrainz servers
Name: libmusicbrainz5
-Version: 5.0.1
-Release: 11%{?dist}
+Version: 5.1.0
+Release: 1%{?dist}
License: LGPLv2
Group: System Environment/Libraries
URL: http://www.musicbrainz.org/
-# Source0: https://github.com/downloads/metabrainz/libmusicbrainz/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: 0001-xmlparsing.patch
+Source0: https://github.com/metabrainz/libmusicbrainz/releases/download/release-5.1.0/libmusicbrainz-%{version}.tar.gz
# Filed upstream as http://tickets.musicbrainz.org/browse/LMB-41
-Patch1: doxygen.patch
+Patch0: doxygen.patch
BuildRequires: cmake
BuildRequires: doxygen
-BuildRequires: neon-devel
-BuildRequires: libxml2-devel
+BuildRequires: pkgconfig(neon)
+BuildRequires: pkgconfig(libxml-2.0)
Obsoletes: libmusicbrainz4 < 4.0.3-5
%description
@@ -42,8 +35,7 @@ applications which will use %{name}.
%prep
%setup -q -n libmusicbrainz-%{version}
-%patch0 -p1 -b .xmlParser
-%patch1 -p1 -b .doxygen
+%patch0 -p1 -b .doxygen
# omit "Generated on ..." timestamps that induce multilib conflicts
# this is *supposed* to be the doxygen default in fedora these days, but
@@ -72,7 +64,7 @@ rm -f docs/installdox
%files
%doc AUTHORS.txt COPYING.txt NEWS.txt README.md
-%{_libdir}/libmusicbrainz5.so.0*
+%{_libdir}/libmusicbrainz5.so.1*
%files devel
%doc docs/*
@@ -82,6 +74,11 @@ rm -f docs/installdox
%changelog
+* Sat Nov 15 2014 David King 5.1.0-1
+- Update to 5.1.0 (#1164434)
+- Drop libxml2 patch (fixed upstream)
+- Use pkgconfig for BuildRequires
+
* Sun Aug 17 2014 Fedora Release Engineering - 5.0.1-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
diff --git a/sources b/sources
index 91cab6a..570798d 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-1abebd606bca260c5f5f6936f6e304ff libmusicbrainz-5.0.1-clean.tar.gz
+4cc5556aa40ff7ab8f8cb83965535bc3 libmusicbrainz-5.1.0.tar.gz