XMLStorage update to prepare for rbuild integration Modified: trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp Modified: trunk/reactos/base/shell/explorer/utility/xmlstorage.h _____
Modified: trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp --- trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp 2006-02-08 08:47:46 UTC (rev 106) +++ trunk/reactos/base/shell/explorer/utility/xmlstorage.cpp 2006-02-12 10:35:41 UTC (rev 107) @@ -4,7 +4,7 @@
// // xmlstorage.cpp // - // Copyright (c) 2004, 2005 Martin Fuchs martin-fuchs@gmx.net + // Copyright (c) 2004, 2005, 2006 Martin Fuchs martin-fuchs@gmx.net //
@@ -48,7 +48,8 @@ #ifdef __GNUC__ const LPCXSSTR XMLStorage::XS_TRUE = XS_TRUE_STR; const LPCXSSTR XMLStorage::XS_FALSE = XS_FALSE_STR; -const LPCXSSTR XMLStorage::XS_NUMBERFMT = XS_NUMBERFMT_STR; +const LPCXSSTR XMLStorage::XS_INTFMT = XS_INTFMT_STR; +const LPCXSSTR XMLStorage::XS_FLOATFMT = XS_FLOATFMT_STR; #endif
@@ -143,7 +144,7 @@ if (slash == path) return NULL;
- int l = slash? slash-path: strlen(path); + size_t l = slash? slash-path: strlen(path); std::string comp(path, l); path += l;
@@ -265,201 +266,6 @@ }
- /// read XML stream into XML tree below _pos -XML_Status XMLReaderBase::read() -{ - XML_Status status = XML_STATUS_OK; - - while(status == XML_STATUS_OK) { - char* buffer = (char*) XML_GetBuffer(_parser, BUFFER_LEN); - - int l = read_buffer(buffer, BUFFER_LEN); - if (l < 0) - break; - - status = XML_ParseBuffer(_parser, l, false); - } - - if (status != XML_STATUS_ERROR) - status = XML_ParseBuffer(_parser, 0, true); - - if (_pos->_children.empty()) - _pos->_trailing.append(_content); - else - _pos->_children.back()->_trailing.append(_content); - - _content.erase(); - - return status; -} - - - /// store XML version and encoding into XML reader -void XMLCALL XMLReaderBase::XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone) -{ - XMLReaderBase* pReader = (XMLReaderBase*) userData; - - if (version) - pReader->_xml_version = version; - - if (encoding) - pReader->_encoding = encoding; -} - - /// notifications about XML start tag -void XMLCALL XMLReaderBase::XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts) -{ - XMLReaderBase* pReader = (XMLReaderBase*) userData; - XMLPos& pos = pReader->_pos; - - // search for end of first line - const char* s = pReader->_content.c_str(); - const char* p = s; - const char* e = p + pReader->_content.length(); - - for(; p<e; ++p) - if (*p == '\n') { - ++p; - break; - } - - if (p != s) - if (pos->_children.empty()) { // no children in last node? - if (pReader->_last_tag == TAG_START) - pos->_content.append(s, p-s); - else if (pReader->_last_tag == TAG_END) - pos->_trailing.append(s, p-s); - // else TAG_NONE -> don't store white space in root node - } else - pos->_children.back()->_trailing.append(s, p-s); - - std::string leading; - - if (p != e) - leading.assign(p, e-p); - - XMLNode* node = new XMLNode(String_from_XML_Char(name), leading); - - pos.add_down(node); - - while(*atts) { - const XML_Char* attr_name = *atts++; - const XML_Char* attr_value = *atts++; - - (*node)[String_from_XML_Char(attr_name)] = String_from_XML_Char(attr_value); - } - - pReader->_last_tag = TAG_START; - pReader->_content.erase(); -} - - /// notifications about XML end tag -void XMLCALL XMLReaderBase::XML_EndElementHandler(void* userData, const XML_Char* name) -{ - XMLReaderBase* pReader = (XMLReaderBase*) userData; - XMLPos& pos = pReader->_pos; - - // search for end of first line - const char* s = pReader->_content.c_str(); - const char* p = s; - const char* e = p + pReader->_content.length(); - - for(; p<e; ++p) - if (*p == '\n') { - ++p; - break; - } - - if (p != s) - if (pos->_children.empty()) // no children in current node? - pos->_content.append(s, p-s); - else - if (pReader->_last_tag == TAG_START) - pos->_content.append(s, p-s); - else - pos->_children.back()->_trailing.append(s, p-s); - - if (p != e) - pos->_end_leading.assign(p, e-p); - - pos.back(); - - pReader->_last_tag = TAG_END; - pReader->_content.erase(); -} - - /// store content, white space and comments -void XMLCALL XMLReaderBase::XML_DefaultHandler(void* userData, const XML_Char* s, int len) -{ - XMLReaderBase* pReader = (XMLReaderBase*) userData; - - pReader->_content.append(s, len); -} - - - /// return error strings for Expat errors -std::string XMLReaderBase::get_error_string() const -{ - XML_Error error = XML_GetErrorCode(_parser); - - switch(error) { - case XML_ERROR_NONE: return "XML_ERROR_NONE"; - case XML_ERROR_NO_MEMORY: return "XML_ERROR_NO_MEMORY"; - case XML_ERROR_SYNTAX: return "XML_ERROR_SYNTAX"; - case XML_ERROR_NO_ELEMENTS: return "XML_ERROR_NO_ELEMENTS"; - case XML_ERROR_INVALID_TOKEN: return "XML_ERROR_INVALID_TOKEN"; - case XML_ERROR_UNCLOSED_TOKEN: return "XML_ERROR_UNCLOSED_TOKEN"; - case XML_ERROR_PARTIAL_CHAR: return "XML_ERROR_PARTIAL_CHAR"; - case XML_ERROR_TAG_MISMATCH: return "XML_ERROR_TAG_MISMATCH"; - case XML_ERROR_DUPLICATE_ATTRIBUTE: return "XML_ERROR_DUPLICATE_ATTRIBUTE"; - case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: return "XML_ERROR_JUNK_AFTER_DOC_ELEMENT"; - case XML_ERROR_PARAM_ENTITY_REF: return "XML_ERROR_PARAM_ENTITY_REF"; - case XML_ERROR_UNDEFINED_ENTITY: return "XML_ERROR_UNDEFINED_ENTITY"; - case XML_ERROR_RECURSIVE_ENTITY_REF: return "XML_ERROR_RECURSIVE_ENTITY_REF"; - case XML_ERROR_ASYNC_ENTITY: return "XML_ERROR_ASYNC_ENTITY"; - case XML_ERROR_BAD_CHAR_REF: return "XML_ERROR_BAD_CHAR_REF"; - case XML_ERROR_BINARY_ENTITY_REF: return "XML_ERROR_BINARY_ENTITY_REF"; - case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: return "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF"; - case XML_ERROR_MISPLACED_XML_PI: return "XML_ERROR_MISPLACED_XML_PI"; - case XML_ERROR_UNKNOWN_ENCODING: return "XML_ERROR_UNKNOWN_ENCODING"; - case XML_ERROR_INCORRECT_ENCODING: return "XML_ERROR_INCORRECT_ENCODING"; - case XML_ERROR_UNCLOSED_CDATA_SECTION: return "XML_ERROR_UNCLOSED_CDATA_SECTION"; - case XML_ERROR_EXTERNAL_ENTITY_HANDLING: return "XML_ERROR_EXTERNAL_ENTITY_HANDLING"; - case XML_ERROR_NOT_STANDALONE: return "XML_ERROR_NOT_STANDALONE"; - case XML_ERROR_UNEXPECTED_STATE: return "XML_ERROR_UNEXPECTED_STATE"; - case XML_ERROR_ENTITY_DECLARED_IN_PE: return "XML_ERROR_ENTITY_DECLARED_IN_PE"; - case XML_ERROR_FEATURE_REQUIRES_XML_DTD: return "XML_ERROR_FEATURE_REQUIRES_XML_DTD"; - case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: return "XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING"; - case XML_ERROR_UNBOUND_PREFIX: return "XML_ERROR_UNBOUND_PREFIX"; - // EXPAT version >= 1.95.8 -#if XML_MAJOR_VERSION>1 || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION>95) || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION==95 && XML_MICRO_VERSION>7) - case XML_ERROR_UNDECLARING_PREFIX: return "XML_ERROR_UNDECLARING_PREFIX"; - case XML_ERROR_INCOMPLETE_PE: return "XML_ERROR_INCOMPLETE_PE"; - case XML_ERROR_XML_DECL: return "XML_ERROR_XML_DECL"; - case XML_ERROR_TEXT_DECL: return "XML_ERROR_TEXT_DECL"; - case XML_ERROR_PUBLICID: return "XML_ERROR_PUBLICID"; - case XML_ERROR_SUSPENDED: return "XML_ERROR_SUSPENDED"; - case XML_ERROR_NOT_SUSPENDED: return "XML_ERROR_NOT_SUSPENDED"; - case XML_ERROR_ABORTED: return "XML_ERROR_ABORTED"; - case XML_ERROR_FINISHED: return "XML_ERROR_FINISHED"; - case XML_ERROR_SUSPEND_PE: return "XML_ERROR_SUSPEND_PE"; -#endif -#if XML_MAJOR_VERSION>=2 - /* Added in 2.0. */ - case XML_ERROR_RESERVED_PREFIX_XML: return "XML_ERROR_RESERVED_PREFIX_XML"; - case XML_ERROR_RESERVED_PREFIX_XMLNS: return "XML_ERROR_RESERVED_PREFIX_XMLNS"; - case XML_ERROR_RESERVED_NAMESPACE_URI: return "XML_ERROR_RESERVED_NAMESPACE_URI"; -#endif - } - - std::ostringstream out; - - out << "XML parser error #" << error; - - return out.str(); -} - - /// encode XML string literals std::string EncodeXMLString(const XS_String& str) { @@ -635,4 +441,284 @@ }
+ /// read XML stream into XML tree below _pos +XML_Status XMLReaderBase::read() +{ + XML_Status status = XML_STATUS_OK; + + while(status == XML_STATUS_OK) { + char* buffer = (char*) XML_GetBuffer(_parser, BUFFER_LEN); + + size_t l = read_buffer(buffer, BUFFER_LEN); + if ((int)l < 0) + break; + + status = XML_ParseBuffer(_parser, l, false); + } + + if (status != XML_STATUS_ERROR) + status = XML_ParseBuffer(_parser, 0, true); + + finish_read(); + + return status; +} + + + /// return current parser position as string +std::string XMLReaderBase::get_position() const +{ + int line = XML_GetCurrentLineNumber(_parser); + int column = XML_GetCurrentColumnNumber(_parser); + + std::ostringstream out; + out << "(" << line << ") : [column " << column << "]"; + + return out.str(); +} + + +#ifdef XMLNODE_LOCATION + +XMLLocation XMLReaderBase::get_location() const +{ + int line = XML_GetCurrentLineNumber(_parser); + int column = XML_GetCurrentColumnNumber(_parser); + + return XMLLocation(_display_path, line, column); +} + +std::string XMLLocation::str() const +{ + std::ostringstream out; + + if (_pdisplay_path) + out << _pdisplay_path; + + out << "(" << _line << ") : [column " << _column << "]"; + + return out.str(); +} + +#endif + + + /// return current error code from Expat +XML_Error XMLReaderBase::get_error_code() const +{ + return XML_GetErrorCode(_parser); +} + + + /// store XML version and encoding into XML reader +void XMLCALL XMLReaderBase::XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone) +{ + XMLReaderBase* pReader = (XMLReaderBase*) userData; + + pReader->XmlDeclHandler(version, encoding, standalone); +} + + /// notifications about XML start tag +void XMLCALL XMLReaderBase::XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts) +{ + XMLReaderBase* pReader = (XMLReaderBase*) userData; + + XMLNode::AttributeMap attributes; + + while(*atts) { + const XML_Char* attr_name = *atts++; + const XML_Char* attr_value = *atts++; + + attributes[String_from_XML_Char(attr_name)] = String_from_XML_Char(attr_value); + } + + pReader->StartElementHandler(String_from_XML_Char(name), attributes); +} + + /// notifications about XML end tag +void XMLCALL XMLReaderBase::XML_EndElementHandler(void* userData, const XML_Char* name) +{ + XMLReaderBase* pReader = (XMLReaderBase*) userData; + + pReader->EndElementHandler(); +} + + /// store content, white space and comments +void XMLCALL XMLReaderBase::XML_DefaultHandler(void* userData, const XML_Char* s, int len) +{ + XMLReaderBase* pReader = (XMLReaderBase*) userData; + + pReader->DefaultHandler(s, len); +} + + + /// return error strings for Expat errors +std::string XMLReaderBase::get_error_string() const +{ + XML_Error error = XML_GetErrorCode(_parser); + + switch(error) { + case XML_ERROR_NONE: return "XML_ERROR_NONE"; + case XML_ERROR_NO_MEMORY: return "XML_ERROR_NO_MEMORY"; + case XML_ERROR_SYNTAX: return "XML_ERROR_SYNTAX"; + case XML_ERROR_NO_ELEMENTS: return "XML_ERROR_NO_ELEMENTS"; + case XML_ERROR_INVALID_TOKEN: return "XML_ERROR_INVALID_TOKEN"; + case XML_ERROR_UNCLOSED_TOKEN: return "XML_ERROR_UNCLOSED_TOKEN"; + case XML_ERROR_PARTIAL_CHAR: return "XML_ERROR_PARTIAL_CHAR"; + case XML_ERROR_TAG_MISMATCH: return "XML_ERROR_TAG_MISMATCH"; + case XML_ERROR_DUPLICATE_ATTRIBUTE: return "XML_ERROR_DUPLICATE_ATTRIBUTE"; + case XML_ERROR_JUNK_AFTER_DOC_ELEMENT: return "XML_ERROR_JUNK_AFTER_DOC_ELEMENT"; + case XML_ERROR_PARAM_ENTITY_REF: return "XML_ERROR_PARAM_ENTITY_REF"; + case XML_ERROR_UNDEFINED_ENTITY: return "XML_ERROR_UNDEFINED_ENTITY"; + case XML_ERROR_RECURSIVE_ENTITY_REF: return "XML_ERROR_RECURSIVE_ENTITY_REF"; + case XML_ERROR_ASYNC_ENTITY: return "XML_ERROR_ASYNC_ENTITY"; + case XML_ERROR_BAD_CHAR_REF: return "XML_ERROR_BAD_CHAR_REF"; + case XML_ERROR_BINARY_ENTITY_REF: return "XML_ERROR_BINARY_ENTITY_REF"; + case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF: return "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF"; + case XML_ERROR_MISPLACED_XML_PI: return "XML_ERROR_MISPLACED_XML_PI"; + case XML_ERROR_UNKNOWN_ENCODING: return "XML_ERROR_UNKNOWN_ENCODING"; + case XML_ERROR_INCORRECT_ENCODING: return "XML_ERROR_INCORRECT_ENCODING"; + case XML_ERROR_UNCLOSED_CDATA_SECTION: return "XML_ERROR_UNCLOSED_CDATA_SECTION"; + case XML_ERROR_EXTERNAL_ENTITY_HANDLING: return "XML_ERROR_EXTERNAL_ENTITY_HANDLING"; + case XML_ERROR_NOT_STANDALONE: return "XML_ERROR_NOT_STANDALONE"; + case XML_ERROR_UNEXPECTED_STATE: return "XML_ERROR_UNEXPECTED_STATE"; + case XML_ERROR_ENTITY_DECLARED_IN_PE: return "XML_ERROR_ENTITY_DECLARED_IN_PE"; + case XML_ERROR_FEATURE_REQUIRES_XML_DTD: return "XML_ERROR_FEATURE_REQUIRES_XML_DTD"; + case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING: return "XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING"; + case XML_ERROR_UNBOUND_PREFIX: return "XML_ERROR_UNBOUND_PREFIX"; + // EXPAT version >= 1.95.8 +#if XML_MAJOR_VERSION>1 || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION>95) || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION==95 && XML_MICRO_VERSION>7) + case XML_ERROR_UNDECLARING_PREFIX: return "XML_ERROR_UNDECLARING_PREFIX"; + case XML_ERROR_INCOMPLETE_PE: return "XML_ERROR_INCOMPLETE_PE"; + case XML_ERROR_XML_DECL: return "XML_ERROR_XML_DECL"; + case XML_ERROR_TEXT_DECL: return "XML_ERROR_TEXT_DECL"; + case XML_ERROR_PUBLICID: return "XML_ERROR_PUBLICID"; + case XML_ERROR_SUSPENDED: return "XML_ERROR_SUSPENDED"; + case XML_ERROR_NOT_SUSPENDED: return "XML_ERROR_NOT_SUSPENDED"; + case XML_ERROR_ABORTED: return "XML_ERROR_ABORTED"; + case XML_ERROR_FINISHED: return "XML_ERROR_FINISHED"; + case XML_ERROR_SUSPEND_PE: return "XML_ERROR_SUSPEND_PE"; +#endif +#if XML_MAJOR_VERSION>=2 + /* Added in 2.0. */ + case XML_ERROR_RESERVED_PREFIX_XML: return "XML_ERROR_RESERVED_PREFIX_XML"; + case XML_ERROR_RESERVED_PREFIX_XMLNS: return "XML_ERROR_RESERVED_PREFIX_XMLNS"; + case XML_ERROR_RESERVED_NAMESPACE_URI: return "XML_ERROR_RESERVED_NAMESPACE_URI"; +#endif + } + + std::ostringstream out; + + out << "XML parser error #" << error; + + return out.str(); +} + + +void XMLReaderBase::finish_read() +{ + if (_pos->_children.empty()) + _pos->_trailing.append(_content); + else + _pos->_children.back()->_trailing.append(_content); + + _content.erase(); +} + + + /// store XML version and encoding into XML reader +void XMLReaderBase::XmlDeclHandler(const XML_Char* version, const XML_Char* encoding, int standalone) +{ + if (version) + _xml_version = version; + + if (encoding) + _encoding = encoding; +} + + + /// notifications about XML start tag +void XMLReaderBase::StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attributes) +{ + // search for end of first line + const char* s = _content.c_str(); + const char* p = s; + const char* e = p + _content.length(); + + for(; p<e; ++p) + if (*p == '\n') { + ++p; + break; + } + + if (p != s) + if (_pos->_children.empty()) { // no children in last node? + if (_last_tag == TAG_START) + _pos->_content.append(s, p-s); + else if (_last_tag == TAG_END) + _pos->_trailing.append(s, p-s); + // else TAG_NONE -> don't store white space in root node + } else + _pos->_children.back()->_trailing.append(s, p-s); + + std::string leading; + + if (p != e) + leading.assign(p, e-p); + + XMLNode* node = new XMLNode(name, leading); + + _pos.add_down(node); + +#ifdef XMLNODE_LOCATION + node->_location = get_location(); +#endif + + node->_attributes = attributes; + + _last_tag = TAG_START; + _content.erase(); +} + + /// notifications about XML end tag +void XMLReaderBase::EndElementHandler() +{ + // search for end of first line + const char* s = _content.c_str(); + const char* p = s; + const char* e = p + _content.length(); + + for(; p<e; ++p) + if (*p == '\n') { + ++p; + break; + } + + if (p != s) + if (_pos->_children.empty()) // no children in current node? + _pos->_content.append(s, p-s); + else + if (_last_tag == TAG_START) + _pos->_content.append(s, p-s); + else + _pos->_children.back()->_trailing.append(s, p-s); + + if (p != e) + _pos->_end_leading.assign(p, e-p); + + _pos.back(); + + _last_tag = TAG_END; + _content.erase(); +} + + /// store content, white space and comments +void XMLReaderBase::DefaultHandler(const XML_Char* s, int len) +{ + _content.append(s, len); +} + + +XS_String XMLWriter::s_empty_attr; + } // namespace XMLStorage _____
Modified: trunk/reactos/base/shell/explorer/utility/xmlstorage.h --- trunk/reactos/base/shell/explorer/utility/xmlstorage.h 2006-02-08 08:47:46 UTC (rev 106) +++ trunk/reactos/base/shell/explorer/utility/xmlstorage.h 2006-02-12 10:35:41 UTC (rev 107) @@ -4,7 +4,7 @@
// // xmlstorage.h // - // Copyright (c) 2004, 2005 Martin Fuchs martin-fuchs@gmx.net + // Copyright (c) 2004, 2005, 2006 Martin Fuchs martin-fuchs@gmx.net //
@@ -38,19 +38,91 @@
#ifndef _XMLSTORAGE_H
+ +#if _MSC_VER>=1400 +#ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES +#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 +#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 1 +#define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1 +#endif +#endif + + +#ifndef _NO_EXPAT + +//#include "expat.h" #include <expat/expat.h>
+#else + +typedef char XML_Char; + +enum XML_Status { + XML_STATUS_ERROR = 0, + XML_STATUS_OK = 1 +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_FAILURE +}; + +#endif + + #ifdef _MSC_VER -#pragma comment(lib, "libexpat.lib") #pragma warning(disable: 4786) + +#ifndef _NO_COMMENT +#ifndef _NO_EXPAT +#ifdef XML_STATIC +#ifndef _DEBUG +#pragma comment(lib, "libexpatMT") #endif +#else +#pragma comment(lib, "libexpat") +#endif +#endif
+#ifndef _STRING_DEFINED // _STRING_DEFINED only allowed if using xmlstorage.cpp embedded in the project +#if defined(_DEBUG) && defined(_DLL) // DEBUG version only supported with MSVCRTD +#if _MSC_VER==1400 +#pragma comment(lib, "xmlstorage-vc8d") +#else +#pragma comment(lib, "xmlstorage-vc6d") +#endif +#else +#ifdef _DLL +#if _MSC_VER==1400 +#pragma comment(lib, "xmlstorage-vc8") +#else +#pragma comment(lib, "xmlstorage-vc6") +#endif +#elif defined(_MT) +#if _MSC_VER==1400 +#pragma comment(lib, "xmlstorage-vc8t") +#else +#pragma comment(lib, "xmlstorage-vc6t") +#endif +#else + // -ML is no more supported by VS2005. +#pragma comment(lib, "xmlstorage-vc6l") +#endif +#endif +#endif // _STRING_DEFINED
+#endif // _NO_COMMENT + +#endif // _MSC_VER + + #include <windows.h> // for LPCTSTR
#ifdef UNICODE +#ifndef _UNICODE #define _UNICODE #endif +#endif
#include <tchar.h> #include <malloc.h> @@ -81,6 +153,7 @@ #define XS_icmp stricmp #define XS_nicmp strnicmp #define XS_toi atoi +#define XS_tod strtod #define XS_len strlen #define XS_snprintf snprintf #define XS_vsnprintf vsnprintf @@ -92,14 +165,19 @@ #define XS_icmp _tcsicmp #define XS_nicmp _tcsnicmp #define XS_toi _ttoi +#define XS_tod _tcstod #define XS_len _tcslen #define XS_snprintf _sntprintf #define XS_vsnprintf _vsntprintf #endif
#ifndef COUNTOF +#if _MSC_VER>=1400 +#define COUNTOF _countof +#else #define COUNTOF(b) (sizeof(b)/sizeof(b[0])) #endif +#endif
#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
@@ -269,7 +347,6 @@ typedef std::filebuf STDIO_FILEBUF; #endif
- struct FileHolder { FileHolder(LPCTSTR path, LPCTSTR mode) @@ -382,6 +459,34 @@ #endif
+#ifdef XMLNODE_LOCATION + /// location of XML Node including XML file name +struct XMLLocation +{ + XMLLocation() + : _pdisplay_path(NULL), + _line(0), + _column(0) + { + } + + XMLLocation(const char* display_path, int line, int column) + : _pdisplay_path(display_path), + _line(line), + _column(column) + { + } + + std::string str() const; + +protected: + const char* _pdisplay_path; // character pointer for fast reference + int _line; + int _column; +}; +#endif + + /// in memory representation of an XML node struct XMLNode : public XS_String { @@ -454,7 +559,8 @@ }
XMLNode(const XMLNode& other) - : _attributes(other._attributes), + : XS_String(other), + _attributes(other._attributes), _leading(other._leading), _content(other._content), _end_leading(other._end_leading), @@ -462,6 +568,10 @@ { for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it) _children.push_back(new XMLNode(**it)); + +#ifdef XMLNODE_LOCATION + _location = other._location; +#endif }
~XMLNode() @@ -588,6 +698,16 @@ return _children; }
+ const AttributeMap& get_attributes() const + { + return _attributes; + } + + AttributeMap& get_attributes() + { + return _attributes; + } + XS_String get_content() const { #ifdef XS_STRING_UTF8 @@ -605,6 +725,10 @@ _content.assign(EncodeXMLString(s.c_str())); }
+#ifdef XMLNODE_LOCATION + const XMLLocation& get_location() const {return _location;} +#endif + enum WRITE_MODE { FORMAT_SMART = 0, /// preserve original white space and comments if present; pretty print otherwise FORMAT_ORIGINAL = 1, /// write XML stream preserving original white space and comments @@ -639,6 +763,10 @@ std::string _end_leading; std::string _trailing;
+#ifdef XMLNODE_LOCATION + XMLLocation _location; +#endif + XMLNode* get_first_child() const { if (!_children.empty()) @@ -706,9 +834,9 @@ /// relative XPath create function XMLNode* create_relative(const char* path);
- void write_worker(std::ostream& out, int indent) const; - void pretty_write_worker(std::ostream& out, int indent) const; - void smart_write_worker(std::ostream& out, int indent) const; + void write_worker(std::ostream& out, int indent) const; + void pretty_write_worker(std::ostream& out, int indent) const; + void smart_write_worker(std::ostream& out, int indent) const; };
@@ -1242,17 +1370,20 @@
#define XS_TRUE_STR XS_TEXT("true") #define XS_FALSE_STR XS_TEXT("false") -#define XS_NUMBERFMT_STR XS_TEXT("%d") +#define XS_INTFMT_STR XS_TEXT("%d") +#define XS_FLOATFMT_STR XS_TEXT("%f")
// work around GCC's wide string constant bug #ifdef __GNUC__ extern const LPCXSSTR XS_TRUE; extern const LPCXSSTR XS_FALSE; -extern const LPCXSSTR XS_NUMBERFMT; +extern const LPCXSSTR XS_INTFMT; +extern const LPCXSSTR XS_FLOATFMT; #else #define XS_TRUE XS_TRUE_STR #define XS_FALSE XS_FALSE_STR -#define XS_NUMBERFMT XS_NUMBERFMT_STR +#define XS_INTFMT XS_INTFMT_STR +#define XS_FLOATFMT XS_FLOATFMT_STR #endif
@@ -1380,7 +1511,7 @@ operator XS_String() const { XS_CHAR buffer[32]; - XS_snprintf(buffer, COUNTOF(buffer), XS_NUMBERFMT, _value); + XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, _value); return buffer; }
@@ -1416,7 +1547,7 @@ void assign(int value) { XS_CHAR buffer[32]; - XS_snprintf(buffer, COUNTOF(buffer), XS_NUMBERFMT, value); + XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, value); _ref.assign(buffer); }
@@ -1425,6 +1556,89 @@ };
+ /// type converter for numeric data +struct XMLDouble +{ + XMLDouble(double value) + : _value(value) + { + } + + XMLDouble(LPCXSSTR value, double def=0.) + { + LPTSTR end; + + if (value && *value) + _value = XS_tod(value, &end); + else + _value = def; + } + + XMLDouble(const XMLNode* node, const XS_String& attr_name, double def=0.) + { + LPTSTR end; + const XS_String& value = node->get(attr_name); + + if (!value.empty()) + _value = XS_tod(value.c_str(), &end); + else + _value = def; + } + + operator double() const + { + return _value; + } + + operator XS_String() const + { + XS_CHAR buffer[32]; + XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, _value); + return buffer; + } + +protected: + double _value; + +private: + void operator=(const XMLDouble&); // disallow assignment operations +}; + + /// type converter for numeric data with write access +struct XMLDoubleRef +{ + XMLDoubleRef(XMLNode* node, const XS_String& attr_name, double def=0.) + : _ref((*node)[attr_name]) + { + if (_ref.empty()) + assign(def); + } + + XMLDoubleRef& operator=(double value) + { + assign(value); + + return *this; + } + + operator double() const + { + LPTSTR end; + return XS_tod(_ref.c_str(), &end); + } + + void assign(double value) + { + XS_CHAR buffer[32]; + XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, value); + _ref.assign(buffer); + } + +protected: + XS_String& _ref; +}; + + /// type converter for string data struct XMLString { @@ -1552,24 +1766,20 @@
XML_Status read();
- virtual int read_buffer(char* buffer, int len) = 0; + std::string get_position() const; + std::string get_instructions() const {return _instructions;}
- std::string get_position() const - { - int line = XML_GetCurrentLineNumber(_parser); - int column = XML_GetCurrentColumnNumber(_parser); + XML_Error get_error_code() const; + std::string get_error_string() const;
- std::ostringstream out; - out << "(" << line << ") : [column " << column << "]"; +#ifdef XMLNODE_LOCATION + const char* _display_path; // character pointer for fast reference in XMLLocation
- return out.str(); - } + XMLLocation get_location() const; +#endif
- std::string get_instructions() const {return _instructions;} + virtual int read_buffer(char* buffer, int len) = 0;
- XML_Error get_error_code() {return XML_GetErrorCode(_parser);} - std::string get_error_string() const; - protected: XMLPos _pos; XML_Parser _parser; @@ -1580,6 +1790,13 @@ std::string _content; enum {TAG_NONE, TAG_START, TAG_END} _last_tag;
+ void finish_read(); + + virtual void XmlDeclHandler(const XML_Char* version, const XML_Char* encoding, int standalone); + virtual void StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attributes); + virtual void EndElementHandler(); + virtual void DefaultHandler(const XML_Char* s, int len); + static void XMLCALL XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone); static void XMLCALL XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts); static void XMLCALL XML_EndElementHandler(void* userData, const XML_Char* name); @@ -1612,7 +1829,7 @@ };
- /// management of XML file headers + /// Management of XML file headers struct XMLHeader { XMLHeader(const std::string& xml_version="1.0", const std::string& encoding="UTF-8", const std::string& doctype="") @@ -1659,13 +1876,11 @@ read(path); }
- std::istream& read(std::istream& in) + bool read(std::istream& in) { XMLReader reader(this, in);
- read(reader); - - return in; + return read(reader); }
bool read(LPCTSTR path) @@ -1700,6 +1915,11 @@
bool read(XMLReaderBase& reader, const std::string& display_path) { +#ifdef XMLNODE_LOCATION + // make a string copy to handle temporary string objects + _display_path = display_path; + reader._display_path = _display_path.c_str(); +#endif XML_Status status = reader.read();
_header._additional = reader.get_instructions(); @@ -1750,6 +1970,10 @@ XMLHeader _header; XML_Error _last_error; std::string _last_error_msg; + +#ifdef XMLNODE_LOCATION + std::string _display_path; +#endif };
@@ -1848,7 +2072,7 @@ void set_content(const XS_String& s) { [truncated at 1000 lines; 24 more skipped]