• Main Page
  • Namespaces
  • Classes
  • Files
  • Directories
  • File List
  • File Members

xs-expat.cpp

Go to the documentation of this file.
00001 
00002  //
00003  // XML storage C++ classes version 1.5
00004  //
00005  // Copyright (c) 2006, 2010 Martin Fuchs <martin-fuchs@gmx.net>
00006  //
00007 
00008  /// \file xs-expat.cpp
00009  /// XMLStorage code using the Expat parser 
00010 
00011 
00012 /*
00013 
00014   All rights reserved.
00015 
00016   Redistribution and use in source and binary forms, with or without
00017   modification, are permitted provided that the following conditions are met:
00018 
00019   * Redistributions of source code must retain the above copyright
00020     notice, this list of conditions and the following disclaimer.
00021   * Redistributions in binary form must reproduce the above copyright
00022     notice, this list of conditions and the following disclaimer in
00023     the documentation and/or other materials provided with the
00024     distribution.
00025 
00026   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036   POSSIBILITY OF SUCH DAMAGE.
00037 
00038 */
00039 
00040 #ifdef XS_USE_EXPAT
00041 
00042 #ifndef XS_NO_COMMENT
00043 #define XS_NO_COMMENT   // no #pragma comment(lib, ...) statements in .lib files to enable static linking
00044 #endif
00045 
00046 #include "xmlstorage.h"
00047 
00048 
00049 namespace XMLStorage {
00050 
00051 
00052 XMLReaderBase::XMLReaderBase(XMLNode* node)
00053  :  _parser(XML_ParserCreate(NULL)),
00054     _pos(node)
00055 {
00056     XML_SetUserData(_parser, this);
00057     XML_SetXmlDeclHandler(_parser, XML_XmlDeclHandler);
00058     XML_SetElementHandler(_parser, XML_StartElementHandler, XML_EndElementHandler);
00059     XML_SetDefaultHandler(_parser, XML_DefaultHandler);
00060 
00061     _last_tag = TAG_NONE;
00062 }
00063 
00064 XMLReaderBase::~XMLReaderBase()
00065 {
00066     XML_ParserFree(_parser);
00067 }
00068 
00069 
00070  /// read XML stream into XML tree below _pos
00071 void XMLReaderBase::read()
00072 {
00073     XML_Status status = XML_STATUS_OK;
00074 
00075     do {
00076         char* buffer = (char*) XML_GetBuffer(_parser, BUFFER_LEN);
00077 
00078         size_t l = read_buffer(buffer, BUFFER_LEN);
00079         if ((int)l < 0)
00080             break;
00081 
00082         status = XML_ParseBuffer(_parser, l, false);
00083     } while(status == XML_STATUS_OK);
00084 
00085     if (status != XML_STATUS_ERROR)
00086         status = XML_ParseBuffer(_parser, 0, true);
00087 
00088     if (status != XML_STATUS_OK) {
00089         XML_Error error_code = XML_GetErrorCode(_parser);
00090         XMLError error;
00091 
00092         error._message = get_expat_error_string(error_code);
00093         error._line = XML_GetCurrentLineNumber(_parser);
00094         error._column = XML_GetCurrentColumnNumber(_parser);
00095 
00096         if (error_code == XML_ERROR_NO_ELEMENTS)
00097             _warnings.push_back(error);
00098         else
00099             _errors.push_back(error);
00100     }
00101 
00102     finish_read();
00103 }
00104 
00105 
00106  /// return current parser position as string
00107 std::string XMLReaderBase::get_position() const
00108 {
00109     int line = XML_GetCurrentLineNumber(_parser);
00110     int column = XML_GetCurrentColumnNumber(_parser);
00111 
00112     std::ostringstream out;
00113     out << "(" << line << ") : [column " << column << "]";
00114 
00115     return out.str();
00116 }
00117 
00118 
00119 #ifdef XMLNODE_LOCATION
00120 
00121 XMLLocation XMLReaderBase::get_location() const
00122 {
00123     int line = XML_GetCurrentLineNumber(_parser);
00124     int column = XML_GetCurrentColumnNumber(_parser);
00125 
00126     return XMLLocation(_display_path, line, column);
00127 }
00128 
00129 #endif
00130 
00131 
00132  /// store XML version and encoding into XML reader
00133 void XMLCALL XMLReaderBase::XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone)
00134 {
00135     XMLReaderBase* pReader = static_cast<XMLReaderBase*>(userData);
00136 
00137     pReader->XmlDeclHandler(version, encoding, standalone);
00138 }
00139 
00140  /// notifications about XML start tag
00141 void XMLCALL XMLReaderBase::XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts)
00142 {
00143     XMLReaderBase* pReader = static_cast<XMLReaderBase*>(userData);
00144 
00145     XMLNode::AttributeMap attributes;
00146 
00147     while(*atts) {
00148         const XML_Char* attr_name = *atts++;
00149         const XML_Char* attr_value = *atts++;
00150 
00151         attributes[String_from_XML_Char(attr_name)] = String_from_XML_Char(attr_value);
00152     }
00153 
00154     pReader->StartElementHandler(String_from_XML_Char(name), attributes);
00155 }
00156 
00157  /// notifications about XML end tag
00158 void XMLCALL XMLReaderBase::XML_EndElementHandler(void* userData, const XML_Char* name)
00159 {
00160     XMLReaderBase* pReader = static_cast<XMLReaderBase*>(userData);
00161 
00162     pReader->EndElementHandler();
00163 }
00164 
00165  /// store content, white space and comments
00166 void XMLCALL XMLReaderBase::XML_DefaultHandler(void* userData, const XML_Char* s, int len)
00167 {
00168     XMLReaderBase* pReader = static_cast<XMLReaderBase*>(userData);
00169 
00170     pReader->DefaultHandler(s, len);
00171 }
00172 
00173 
00174  /// return error strings for Expat errors
00175 std::string XMLReaderBase::get_expat_error_string(XML_Error error_code)
00176 {
00177     switch(error_code) {
00178       case XML_ERROR_NONE:                              return "XML_ERROR_NONE";
00179       case XML_ERROR_NO_MEMORY:                         return "XML_ERROR_NO_MEMORY";
00180       case XML_ERROR_SYNTAX:                            return "XML_ERROR_SYNTAX";
00181       case XML_ERROR_NO_ELEMENTS:                       return "XML_ERROR_NO_ELEMENTS";
00182       case XML_ERROR_INVALID_TOKEN:                     return "XML_ERROR_INVALID_TOKEN";
00183       case XML_ERROR_UNCLOSED_TOKEN:                    return "XML_ERROR_UNCLOSED_TOKEN";
00184       case XML_ERROR_PARTIAL_CHAR:                      return "XML_ERROR_PARTIAL_CHAR";
00185       case XML_ERROR_TAG_MISMATCH:                      return "XML_ERROR_TAG_MISMATCH";
00186       case XML_ERROR_DUPLICATE_ATTRIBUTE:               return "XML_ERROR_DUPLICATE_ATTRIBUTE";
00187       case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:            return "XML_ERROR_JUNK_AFTER_DOC_ELEMENT";
00188       case XML_ERROR_PARAM_ENTITY_REF:                  return "XML_ERROR_PARAM_ENTITY_REF";
00189       case XML_ERROR_UNDEFINED_ENTITY:                  return "XML_ERROR_UNDEFINED_ENTITY";
00190       case XML_ERROR_RECURSIVE_ENTITY_REF:              return "XML_ERROR_RECURSIVE_ENTITY_REF";
00191       case XML_ERROR_ASYNC_ENTITY:                      return "XML_ERROR_ASYNC_ENTITY";
00192       case XML_ERROR_BAD_CHAR_REF:                      return "XML_ERROR_BAD_CHAR_REF";
00193       case XML_ERROR_BINARY_ENTITY_REF:                 return "XML_ERROR_BINARY_ENTITY_REF";
00194       case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:     return "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF";
00195       case XML_ERROR_MISPLACED_XML_PI:                  return "XML_ERROR_MISPLACED_XML_PI";
00196       case XML_ERROR_UNKNOWN_ENCODING:                  return "XML_ERROR_UNKNOWN_ENCODING";
00197       case XML_ERROR_INCORRECT_ENCODING:                return "XML_ERROR_INCORRECT_ENCODING";
00198       case XML_ERROR_UNCLOSED_CDATA_SECTION:            return "XML_ERROR_UNCLOSED_CDATA_SECTION";
00199       case XML_ERROR_EXTERNAL_ENTITY_HANDLING:          return "XML_ERROR_EXTERNAL_ENTITY_HANDLING";
00200       case XML_ERROR_NOT_STANDALONE:                    return "XML_ERROR_NOT_STANDALONE";
00201       case XML_ERROR_UNEXPECTED_STATE:                  return "XML_ERROR_UNEXPECTED_STATE";
00202       case XML_ERROR_ENTITY_DECLARED_IN_PE:             return "XML_ERROR_ENTITY_DECLARED_IN_PE";
00203       case XML_ERROR_FEATURE_REQUIRES_XML_DTD:          return "XML_ERROR_FEATURE_REQUIRES_XML_DTD";
00204       case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:  return "XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING";
00205       case XML_ERROR_UNBOUND_PREFIX:                    return "XML_ERROR_UNBOUND_PREFIX";
00206  // EXPAT version >= 1.95.8
00207 #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)
00208       case XML_ERROR_UNDECLARING_PREFIX:                return "XML_ERROR_UNDECLARING_PREFIX";
00209       case XML_ERROR_INCOMPLETE_PE:                     return "XML_ERROR_INCOMPLETE_PE";
00210       case XML_ERROR_XML_DECL:                          return "XML_ERROR_XML_DECL";
00211       case XML_ERROR_TEXT_DECL:                         return "XML_ERROR_TEXT_DECL";
00212       case XML_ERROR_PUBLICID:                          return "XML_ERROR_PUBLICID";
00213       case XML_ERROR_SUSPENDED:                         return "XML_ERROR_SUSPENDED";
00214       case XML_ERROR_NOT_SUSPENDED:                     return "XML_ERROR_NOT_SUSPENDED";
00215       case XML_ERROR_ABORTED:                           return "XML_ERROR_ABORTED";
00216       case XML_ERROR_FINISHED:                          return "XML_ERROR_FINISHED";
00217       case XML_ERROR_SUSPEND_PE:                        return "XML_ERROR_SUSPEND_PE";
00218 #endif
00219 #if XML_MAJOR_VERSION>=2
00220         /* Added in 2.0. */
00221       case XML_ERROR_RESERVED_PREFIX_XML:               return "XML_ERROR_RESERVED_PREFIX_XML";
00222       case XML_ERROR_RESERVED_PREFIX_XMLNS:             return "XML_ERROR_RESERVED_PREFIX_XMLNS";
00223       case XML_ERROR_RESERVED_NAMESPACE_URI:            return "XML_ERROR_RESERVED_NAMESPACE_URI";
00224 #endif
00225     }
00226 
00227     std::ostringstream out;
00228 
00229     out << "Expat XML parser error #" << error_code;
00230 
00231     return out.str();
00232 }
00233 
00234 
00235 }   // namespace XMLStorage
00236 
00237 #endif // XS_USE_EXPAT

Generated on Fri Nov 14 2014 00:05:04 for XMLStorage/C++ by  doxygen 1.7.2