xmlparser.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 2004-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Tue May 25 10:29:42 2004
00010 // commit: $Id: xmlparser.cc 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/io/xmlparser.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
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(/*encoding*/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* /*text*/, int /*length*/)
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       // very strangely I wasn't able to get things to work using a
00121       // readsome() approach here...
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       // alternate: use XML_Parse(m_parser, m_buf, len, done) if we have
00144       // our own memory buffer
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 // here's a simple subclass of io::xml_parser that prints an outline
00162 // of an XML file just to show that everything is getting parsed
00163 // properly
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

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:39 2008 by Doxygen version 1.5.5.