00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_IO_XMLPARSER_CC_UTC20050626084021_DEFINED
00035 #define GROOVX_IO_XMLPARSER_CC_UTC20050626084021_DEFINED
00036
00037 #include "io/xmlparser.h"
00038
00039 #include "rutz/error.h"
00040 #include "rutz/fstring.h"
00041 #include "rutz/sfmt.h"
00042
00043 #include <istream>
00044
00045 #include "rutz/trace.h"
00046 #include "rutz/debug.h"
00047 GVX_DBG_REGISTER
00048
00049 #ifndef XML_STATUS_OK
00050 #define XML_STATUS_OK 1
00051 #define XML_STATUS_ERROR 0
00052 #endif
00053
00054 io::xml_parser::xml_parser(std::istream& is, int bufsize) :
00055 m_parser(XML_ParserCreate(0)),
00056 m_stream(is),
00057 m_buf_size(bufsize)
00058 {
00059 GVX_TRACE("io::xml_parser::xml_parser");
00060 if (m_parser == 0)
00061 {
00062 throw rutz::error("couldn't allocate memory for XML_Parser",
00063 SRC_POS);
00064 }
00065
00066 XML_SetUserData(m_parser, this);
00067
00068 XML_SetElementHandler(m_parser, &c_element_start, &c_element_end);
00069
00070 XML_SetCharacterDataHandler(m_parser, &c_character_data);
00071 }
00072
00073 io::xml_parser::~xml_parser()
00074 {
00075 GVX_TRACE("io::xml_parser::~xml_parser");
00076 XML_ParserFree(m_parser);
00077 }
00078
00079 void io::xml_parser::character_data(const char* , int )
00080 {
00081 GVX_TRACE("io::xml_parser::character_data");
00082 }
00083
00084 void io::xml_parser::c_element_start(void* data, const char* el, const char** attr)
00085 {
00086 GVX_TRACE("io::xml_parser::c_element_start");
00087 io::xml_parser* p = static_cast<io::xml_parser*>(data);
00088 GVX_ASSERT(p != 0);
00089 p->element_start(el, attr);
00090 }
00091
00092 void io::xml_parser::c_element_end(void* data, const char* el)
00093 {
00094 GVX_TRACE("io::xml_parser::c_element_end");
00095 io::xml_parser* p = static_cast<io::xml_parser*>(data);
00096 GVX_ASSERT(p != 0);
00097 p->element_end(el);
00098 }
00099
00100 void io::xml_parser::c_character_data(void* data, const char* text, int length)
00101 {
00102 GVX_TRACE("io::xml_parser::c_character_data");
00103 io::xml_parser* p = static_cast<io::xml_parser*>(data);
00104 GVX_ASSERT(p != 0);
00105 p->character_data(text, length);
00106 }
00107
00108 void io::xml_parser::parse()
00109 {
00110 GVX_TRACE("io::xml_parser::parse");
00111 while (1)
00112 {
00113 void* const buf = XML_GetBuffer(m_parser, m_buf_size);
00114 if (buf == 0)
00115 {
00116 throw rutz::error("couldn't get buffer in io::xml_parser::parse()",
00117 SRC_POS);
00118 }
00119
00120
00121
00122 m_stream.read(static_cast<char*>(buf), m_buf_size);
00123 const int len = m_stream.gcount();
00124 if (!m_stream.eof() && m_stream.fail())
00125 {
00126 throw rutz::error("read error in io::xml_parser::parse()",
00127 SRC_POS);
00128 }
00129
00130 const int peek = m_stream.peek();
00131
00132 const int done = (peek == EOF);
00133
00134 if (GVX_DBG_LEVEL() >= 3)
00135 {
00136 dbg_eval(3, buf);
00137 dbg_eval(3, m_buf_size);
00138 dbg_eval(3, len);
00139 dbg_eval(3, peek);
00140 dbg_eval_nl(3, done);
00141 }
00142
00143
00144
00145 if (XML_ParseBuffer(m_parser, len, done)
00146 != XML_STATUS_OK)
00147 {
00148 throw rutz::error
00149 (rutz::sfmt("xml parse error at input line %d:\n%s",
00150 int(XML_GetCurrentLineNumber(m_parser)),
00151 XML_ErrorString(XML_GetErrorCode(m_parser))),
00152 SRC_POS);
00153 }
00154
00155 if (done)
00156 return;
00157 }
00158 }
00159
00160 #if 0
00161
00162
00163
00164 class Outliner : public io::xml_parser
00165 {
00166 public:
00167 Outliner(std::istream& is) :
00168 io::xml_parser(is),
00169 m_depth(0) {}
00170 virtual ~Outliner() {}
00171
00172 protected:
00173 virtual void element_start(const char* el, const char** attr);
00174 virtual void element_end(const char* el);
00175
00176 private:
00177 int m_depth;
00178 };
00179
00180 void Outliner::element_start(const char* el, const char** attr)
00181 {
00182 for (int i = 0; i < m_depth; i++)
00183 printf(" ");
00184
00185 printf("%s", el);
00186
00187 for (int i = 0; attr[i]; i += 2)
00188 {
00189 printf(" %s='%s'", attr[i], attr[i + 1]);
00190 }
00191
00192 printf("\n");
00193 ++m_depth;
00194 }
00195
00196 void Outliner::element_end(const char* el)
00197 {
00198 --m_depth;
00199 }
00200 #endif
00201
00202 static const char __attribute__((used)) vcid_groovx_io_xmlparser_cc_utc20050626084021[] = "$Id: xmlparser.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00203 #endif // !GROOVX_IO_XMLPARSER_CC_UTC20050626084021_DEFINED