Reader.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 extern "C"
00013 {
00014 #include <libxml/xmlreader.h>
00015 #include <libxml/xmlerror.h>
00016 }
00017 
00018 #include <iostream>
00019 
00020 #include "zypp/base/LogControl.h"
00021 #include "zypp/base/LogTools.h"
00022 #include "zypp/base/Exception.h"
00023 
00024 #include "zypp/parser/xml/Reader.h"
00025 
00026 using std::endl;
00027 
00029 namespace zypp
00030 { 
00031 
00032   namespace xml
00033   { 
00034 
00036     namespace
00037     { 
00038 
00039       int ioread( void * context_r, char * buffer_r, int bufferLen_r )
00040       {
00041         if ( context_r && buffer_r )
00042           {
00043             return reinterpret_cast<InputStream *>(context_r)
00044                    ->stream().read( buffer_r, bufferLen_r ).gcount();
00045           }
00046         INT << "XML parser error: null pointer check failed " << context_r << ' ' << (void *)buffer_r << endl;
00047         return -1;
00048       }
00049 
00050       int ioclose( void * /*context_r*/ )
00051       { return 0; }
00052 
00053       void structuredErrorFunc( void * userData, xmlErrorPtr error )
00054       {
00055         if ( error )
00056           {
00057 #define X(m) SEC << " " << #m << "\t" << error->m << endl
00058 #define XS(m) SEC << " " << #m << "\t" << (error->m?error->m:"NA") << endl
00059             X(domain);
00060             X(code);
00061             XS(message);
00062             X(level);
00063             XS(file);
00064             X(line);
00065             XS(str1);
00066             XS(str2);
00067             XS(str3);
00068             X(int1);
00069             X(int2);
00070             X(ctxt);
00071             X(node);
00072 #undef X
00073 #undef XS
00074           }
00075       }
00076 
00078     } // namespace
00080 
00082     //
00083     //  METHOD NAME : Reader::Reader
00084     //  METHOD TYPE : Constructor
00085     //
00086     Reader::Reader( const InputStream & stream_r,
00087                     const Validate & validate_r )
00088     : _stream( stream_r )
00089     , _reader( xmlReaderForIO( ioread, ioclose, &_stream,
00090                                stream_r.path().asString().c_str(), "utf-8", XML_PARSE_PEDANTIC ) )
00091     , _node( _reader )
00092     {
00093       if ( ! _reader || ! stream_r.stream().good() )
00094         ZYPP_THROW( Exception( "Bad input stream" ) );
00095       // set error handler
00096       xmlTextReaderSetStructuredErrorHandler( _reader, structuredErrorFunc, NULL );
00097       // TODO: set validation
00098 
00099       // advance to 1st node
00100       nextNode();
00101     }
00102 
00104     //
00105     //  METHOD NAME : Reader::~Reader
00106     //  METHOD TYPE : Destructor
00107     //
00108     Reader::~Reader()
00109     {
00110       if ( _reader )
00111         {
00112           xmlFreeTextReader( _reader );
00113         }
00114     }
00115 
00117     //
00118     //  METHOD NAME : Reader::nextNode
00119     //  METHOD TYPE : bool
00120     //
00121     bool Reader::nextNode()
00122     {
00123       int ret = xmlTextReaderRead( _reader );
00124       if ( ret == 1 )
00125         {
00126           return true;
00127         }
00128       xmlTextReaderClose( _reader );
00129       if ( ret != 0 )
00130         {
00131           ZYPP_THROW( Exception( "Parse error" ) );
00132         }
00133       return false;
00134     }
00135 
00137     //
00138     //  METHOD NAME : Reader::nextNodeAttribute
00139     //  METHOD TYPE : bool
00140     //
00141     bool Reader::nextNodeAttribute()
00142     {
00143       int ret = xmlTextReaderMoveToNextAttribute( _reader );
00144       if ( ret == 1 )
00145         {
00146           return true;
00147         }
00148       if ( ret != 0 )
00149         {
00150           ZYPP_THROW( Exception( "Parse error" ) );
00151         }
00152       return false;
00153     }
00154 
00156     //
00157     //  METHOD NAME : Reader::close
00158     //  METHOD TYPE : void
00159     //
00160     void Reader::close()
00161     {
00162       if ( _reader )
00163         {
00164           xmlTextReaderClose( _reader );
00165         }
00166     }
00167 
00169     //
00170     //  METHOD NAME : Reader::seekToNode
00171     //  METHOD TYPE : bool
00172     //
00173     bool Reader::seekToNode( int depth_r, const std::string & name_r )
00174     {
00175       do
00176         {
00177           if ( _node.depth() == depth_r
00178                && _node.name() == name_r
00179                && _node.nodeType() == XML_READER_TYPE_ELEMENT )
00180             {
00181               break;
00182             }
00183         } while( nextNode() );
00184 
00185       return ! atEnd();
00186     }
00187 
00189     //
00190     //  METHOD NAME : Reader::seekToEndNode
00191     //  METHOD TYPE : bool
00192     //
00193     bool Reader::seekToEndNode( int depth_r, const std::string & name_r )
00194     {
00195       // Empty element has no separate end node: <node/>
00196       do
00197         {
00198           if ( _node.depth() == depth_r
00199                && _node.name() == name_r
00200                && ( _node.nodeType() == XML_READER_TYPE_END_ELEMENT
00201                     || ( _node.nodeType() == XML_READER_TYPE_ELEMENT
00202                          && _node.isEmptyElement() ) ) )
00203             {
00204               break;
00205             }
00206         } while( nextNode() );
00207 
00208       return ! atEnd();
00209     }
00210 
00212   } // namespace xml
00215 } // namespace zypp

Generated on Thu Apr 24 02:24:50 2008 for zypp by  doxygen 1.4.6