00001
00002
00003
00004
00005
00006
00007
00008
00013 #ifndef XMLNodeIterator_h
00014 #define XMLNodeIterator_h
00015
00016 #include <zypp/parser/LibXMLHelper.h>
00017 #include <iosfwd>
00018
00019
00020 #include "zypp/parser/xml_parser_assert.h"
00021 #include "zypp/Pathname.h"
00022 #include "zypp/parser/ParserProgress.h"
00023 #include <iterator>
00024
00025 extern "C" {
00026 typedef void * xmlTextReaderLocatorPtr;
00027 struct _xmlNode;
00028 typedef struct _xmlNode xmlNode;
00029 typedef xmlNode *xmlNodePtr;
00030
00031 struct _xmlTextReader;
00032 typedef _xmlTextReader xmlTextReader;
00033 typedef xmlTextReader *xmlTextReaderPtr;
00034
00035 struct _xmlError;
00036 typedef _xmlError xmlError;
00037 typedef xmlError *xmlErrorPtr;
00038 }
00039
00040 namespace zypp {
00041
00042 namespace parser {
00043
00044
00048 class XMLParserError {
00049 public:
00053 XMLParserError(const char *msg,
00054 int severity,
00055 xmlTextReaderLocatorPtr locator,
00056 int docLine,
00057 int docColumn) throw();
00058
00059 ~XMLParserError() throw();
00060
00064 std::string msg() const throw();
00065
00069 int severity() const throw();
00070
00074 xmlTextReaderLocatorPtr locator() const throw();
00075
00079 int docLine() const throw();
00080
00084 int docColumn() const throw();
00085
00090 std::string position() const throw();
00091
00092 private:
00093
00094 std::string _msg;
00095 int _severity;
00096 xmlTextReaderLocatorPtr _locator;
00097 int _docLine;
00098 int _docColumn;
00099 };
00100
00101
00102 std::ostream& operator<<(std::ostream &out, const XMLParserError& error);
00103
00104
00105
00135 class XMLNodeIteratorBase {
00136 public:
00143 XMLNodeIteratorBase(std::istream &input,
00144 const std::string &baseUrl,
00145 const char *validationPath, parser::ParserProgress::Ptr progress );
00146
00154 XMLNodeIteratorBase( const Pathname xml_file_path,
00155 const std::string &baseUrl,
00156 const char *validationPath, parser::ParserProgress::Ptr progress);
00157
00163 XMLNodeIteratorBase();
00164
00168 virtual ~XMLNodeIteratorBase();
00169
00175 bool atEnd() const;
00176
00185 bool
00186 operator==(const XMLNodeIteratorBase &other) const;
00187
00193 bool
00194 operator!=(const XMLNodeIteratorBase &otherNode) const
00195 {
00196 return ! operator==(otherNode);
00197 }
00198
00205 const XMLParserError *
00206 errorStatus() const;
00207
00208 protected:
00209
00221 virtual bool
00222 isInterested(const xmlNodePtr nodePtr) = 0;
00223
00237 virtual void
00238 _process(const xmlTextReaderPtr readerPtr) = 0;
00239
00243 void fetchNext();
00244
00255 static void
00256 errorHandler(void * arg,
00257 const char * msg,
00258 int severity,
00259 xmlTextReaderLocatorPtr locator);
00260
00261
00262 virtual void setCurrent(const void *data) = 0;
00263 virtual void* getCurrent() const = 0;
00264
00265 private:
00266
00271 XMLNodeIteratorBase & operator=(const XMLNodeIteratorBase& otherNode);
00272
00281 XMLNodeIteratorBase(const XMLNodeIteratorBase& otherNode);
00282
00286 std::auto_ptr<XMLParserError> _error;
00287
00292 std::istream* _input;
00293
00298 FILE* _file;
00299
00300
00304 xmlTextReaderPtr _reader;
00305
00309 std::string _baseUrl;
00310
00314 parser::ParserProgress::Ptr _progress;
00315
00319 long int _stream_size;
00323 long int _bytes_consumed;
00324 };
00325
00326
00327
00328
00329
00330 template <class ENTRYTYPE>
00331 class XMLNodeIterator : public XMLNodeIteratorBase,
00332 public std::iterator<std::input_iterator_tag, ENTRYTYPE> {
00333 public:
00340 XMLNodeIterator(std::istream &input,
00341 const std::string &baseUrl,
00342 const char *validationPath = 0,
00343 parser::ParserProgress::Ptr progress = parser::ParserProgress::Ptr() )
00344 : XMLNodeIteratorBase(input, baseUrl, validationPath, progress), _current(0)
00345 {
00346
00347
00348
00349 }
00350
00357 XMLNodeIterator( const Pathname xml_file_path, const std::string &baseUrl
00358 , const char *validationPath, parser::ParserProgress::Ptr progress)
00359 : XMLNodeIteratorBase( xml_file_path, baseUrl, validationPath, progress), _current(0)
00360 {
00361 }
00362
00370 XMLNodeIterator(ENTRYTYPE &entry)
00371 : XMLNodeIteratorBase()
00372 {
00373 setCurrent((void *)& entry);
00374 }
00375
00381 XMLNodeIterator()
00382 : XMLNodeIteratorBase(), _current(0)
00383 { }
00384
00388 virtual ~XMLNodeIterator()
00389 { }
00390
00395 ENTRYTYPE &
00396 operator*() const
00397 {
00398 assert (! atEnd());
00399 return * (ENTRYTYPE *) getCurrent();
00400 }
00401
00406 ENTRYTYPE *
00407 operator()() const
00408 {
00409 if (_error)
00410 return 0;
00411 else
00412 return getCurrent();
00413 }
00414
00419 XMLNodeIterator<ENTRYTYPE> &
00420 operator++() {
00421 fetchNext();
00422 return *this;
00423 }
00424
00432 XMLNodeIterator operator++(int)
00433 {
00434 assert (!atEnd());
00435 XMLNodeIterator<ENTRYTYPE> tmp(operator()());
00436 fetchNext();
00437 return tmp;
00438 }
00439
00444 const ENTRYTYPE *
00445 operator->()
00446 {
00447 xml_assert(! atEnd());
00448 return getCurrent();
00449 }
00450
00451 protected:
00452
00464 virtual bool
00465 isInterested(const xmlNodePtr nodePtr) = 0;
00466
00481 virtual ENTRYTYPE
00482 process(const xmlTextReaderPtr readerPtr) = 0;
00483
00484 void
00485 _process(const xmlTextReaderPtr readerPtr)
00486 {
00487 _current.reset( new ENTRYTYPE(process(readerPtr)));
00488 }
00489
00490 private:
00491
00492 void setCurrent(const void *data)
00493 {
00494 if (data)
00495 _current.reset(new ENTRYTYPE(* (ENTRYTYPE *) data));
00496 else
00497 _current.reset(0);
00498 }
00499
00500 void *getCurrent() const
00501 {
00502 return _current.get();
00503 }
00504
00511 std::auto_ptr<ENTRYTYPE> _current;
00512 };
00513
00514 }
00515 }
00516
00517 #endif