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 <iostream>
00018 #include <ostream>
00019 #include <sstream>
00020 #include "zypp/parser/xml_parser_assert.h"
00021 #include <iterator>
00022
00023 extern "C" {
00024 typedef void * xmlTextReaderLocatorPtr;
00025 struct _xmlNode;
00026 typedef struct _xmlNode xmlNode;
00027 typedef xmlNode *xmlNodePtr;
00028
00029 struct _xmlTextReader;
00030 typedef _xmlTextReader xmlTextReader;
00031 typedef xmlTextReader *xmlTextReaderPtr;
00032
00033 struct _xmlError;
00034 typedef _xmlError xmlError;
00035 typedef xmlError *xmlErrorPtr;
00036 }
00037
00038 namespace zypp {
00039
00040 namespace parser {
00041
00042
00046 class XMLParserError {
00047 public:
00051 XMLParserError(const char *msg,
00052 int severity,
00053 xmlTextReaderLocatorPtr locator,
00054 int docLine,
00055 int docColumn) throw();
00056
00057 ~XMLParserError() throw();
00058
00062 std::string msg() const throw();
00063
00067 int severity() const throw();
00068
00072 xmlTextReaderLocatorPtr locator() const throw();
00073
00077 int docLine() const throw();
00078
00082 int docColumn() const throw();
00083
00088 std::string position() const throw();
00089
00090 private:
00091
00092 std::string _msg;
00093 int _severity;
00094 xmlTextReaderLocatorPtr _locator;
00095 int _docLine;
00096 int _docColumn;
00097 };
00098
00099
00100 std::ostream& operator<<(std::ostream &out, const XMLParserError& error);
00101
00102
00103
00133 class XMLNodeIteratorBase {
00134 public:
00141 XMLNodeIteratorBase(std::istream &input,
00142 const std::string &baseUrl,
00143 const char *validationPath = 0);
00144
00150 XMLNodeIteratorBase();
00151
00155 virtual ~XMLNodeIteratorBase();
00156
00162 bool atEnd() const;
00163
00172 bool
00173 operator==(const XMLNodeIteratorBase &other) const;
00174
00180 bool
00181 operator!=(const XMLNodeIteratorBase &otherNode) const
00182 {
00183 return ! operator==(otherNode);
00184 }
00185
00192 const XMLParserError *
00193 errorStatus() const;
00194
00195 protected:
00196
00208 virtual bool
00209 isInterested(const xmlNodePtr nodePtr) = 0;
00210
00224 virtual void
00225 _process(const xmlTextReaderPtr readerPtr) = 0;
00226
00230 void fetchNext();
00231
00242 static void
00243 errorHandler(void * arg,
00244 const char * msg,
00245 int severity,
00246 xmlTextReaderLocatorPtr locator);
00247
00248
00249 virtual void setCurrent(const void *data) = 0;
00250 virtual void* getCurrent() const = 0;
00251
00252 private:
00253
00258 XMLNodeIteratorBase & operator=(const XMLNodeIteratorBase& otherNode);
00259
00268 XMLNodeIteratorBase(const XMLNodeIteratorBase& otherNode);
00269
00273 std::auto_ptr<XMLParserError> _error;
00274
00279 std::istream* _input;
00280
00284 xmlTextReaderPtr _reader;
00285
00289 std::string _baseUrl;
00290 };
00291
00292
00293
00294
00295
00296 template <class ENTRYTYPE>
00297 class XMLNodeIterator : public XMLNodeIteratorBase,
00298 public std::iterator<std::input_iterator_tag, ENTRYTYPE> {
00299 public:
00306 XMLNodeIterator(std::istream &input,
00307 const std::string &baseUrl,
00308 const char *validationPath = 0)
00309 : XMLNodeIteratorBase(input, baseUrl, validationPath), _current(0)
00310 {
00311
00312
00313
00314 }
00315
00316
00324 XMLNodeIterator(ENTRYTYPE &entry)
00325 : XMLNodeIteratorBase()
00326 {
00327 setCurrent((void *)& entry);
00328 }
00329
00335 XMLNodeIterator()
00336 : XMLNodeIteratorBase(), _current(0)
00337 { }
00338
00342 virtual ~XMLNodeIterator()
00343 { }
00344
00349 ENTRYTYPE &
00350 operator*() const
00351 {
00352 assert (! atEnd());
00353 return * (ENTRYTYPE *) getCurrent();
00354 }
00355
00360 ENTRYTYPE *
00361 operator()() const
00362 {
00363 if (_error)
00364 return 0;
00365 else
00366 return getCurrent();
00367 }
00368
00373 XMLNodeIterator<ENTRYTYPE> &
00374 operator++() {
00375 fetchNext();
00376 return *this;
00377 }
00378
00386 XMLNodeIterator operator++(int)
00387 {
00388 assert (!atEnd());
00389 XMLNodeIterator<ENTRYTYPE> tmp(operator()());
00390 fetchNext();
00391 return tmp;
00392 }
00393
00398 const ENTRYTYPE *
00399 operator->()
00400 {
00401 xml_assert(! atEnd());
00402 return getCurrent();
00403 }
00404
00405 protected:
00406
00418 virtual bool
00419 isInterested(const xmlNodePtr nodePtr) = 0;
00420
00435 virtual ENTRYTYPE
00436 process(const xmlTextReaderPtr readerPtr) = 0;
00437
00438 void
00439 _process(const xmlTextReaderPtr readerPtr)
00440 {
00441 _current.reset( new ENTRYTYPE(process(readerPtr)));
00442 }
00443
00444 private:
00445
00446 void setCurrent(const void *data)
00447 {
00448 if (data)
00449 _current.reset(new ENTRYTYPE(* (ENTRYTYPE *) data));
00450 else
00451 _current.reset(0);
00452 }
00453
00454 void *getCurrent() const
00455 {
00456 return _current.get();
00457 }
00458
00465 std::auto_ptr<ENTRYTYPE> _current;
00466 };
00467
00468 }
00469 }
00470
00471 #endif