00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef XMLNodeIterator_h
00023 #define XMLNodeIterator_h
00024
00025 #include <y2util/LibXMLHelper.h>
00026
00027 #include <iostream>
00028 #include <ostream>
00029 #include <sstream>
00030 #include <cassert>
00031 #include <iterator>
00032
00033 extern "C" {
00034 typedef void * xmlTextReaderLocatorPtr;
00035 struct _xmlNode;
00036 typedef struct _xmlNode xmlNode;
00037 typedef xmlNode *xmlNodePtr;
00038
00039 struct _xmlTextReader;
00040 typedef _xmlTextReader xmlTextReader;
00041 typedef xmlTextReader *xmlTextReaderPtr;
00042
00043 struct _xmlError;
00044 typedef _xmlError xmlError;
00045 typedef xmlError *xmlErrorPtr;
00046 }
00047
00048
00049
00050
00054 class XMLParserError {
00055 public:
00059 XMLParserError(const char *msg,
00060 int severity,
00061 xmlTextReaderLocatorPtr locator,
00062 int docLine,
00063 int docColumn) throw();
00064
00065 ~XMLParserError() throw();
00066
00070 std::string msg() const throw();
00071
00075 int severity() const throw();
00076
00080 xmlTextReaderLocatorPtr locator() const throw();
00081
00085 int docLine() const throw();
00086
00090 int docColumn() const throw();
00091
00096 std::string position() const throw();
00097
00098 private:
00099
00100 std::string _msg;
00101 int _severity;
00102 xmlTextReaderLocatorPtr _locator;
00103 int _docLine;
00104 int _docColumn;
00105 };
00106
00107
00108 std::ostream& operator<<(std::ostream &out, const XMLParserError& error);
00109
00110
00111
00141 class XMLNodeIteratorBase {
00142 public:
00149 XMLNodeIteratorBase(std::istream &input,
00150 const std::string &baseUrl,
00151 const char *validationPath = 0);
00152
00158 XMLNodeIteratorBase();
00159
00163 virtual ~XMLNodeIteratorBase();
00164
00170 bool atEnd() const;
00171
00180 bool
00181 operator==(const XMLNodeIteratorBase &other) const;
00182
00188 bool
00189 operator!=(const XMLNodeIteratorBase &otherNode) const
00190 {
00191 return ! operator==(otherNode);
00192 }
00193
00200 const XMLParserError *
00201 errorStatus() const;
00202
00203 protected:
00204
00216 virtual bool
00217 isInterested(const xmlNodePtr nodePtr) = 0;
00218
00232 virtual void
00233 _process(const xmlTextReaderPtr readerPtr) = 0;
00234
00238 void fetchNext();
00239
00250 static void
00251 errorHandler(void * arg,
00252 const char * msg,
00253 int severity,
00254 xmlTextReaderLocatorPtr locator);
00255
00256
00257 virtual void setCurrent(const void *data) = 0;
00258 virtual void* getCurrent() const = 0;
00259
00260 private:
00261
00266 XMLNodeIteratorBase & operator=(const XMLNodeIteratorBase& otherNode);
00267
00276 XMLNodeIteratorBase(const XMLNodeIteratorBase& otherNode);
00277
00281 std::auto_ptr<XMLParserError> _error;
00282
00287 std::istream* _input;
00288
00292 xmlTextReaderPtr _reader;
00293
00297 std::string _baseUrl;
00298 };
00299
00300
00301
00302
00303
00304 template <class ENTRYTYPE>
00305 class XMLNodeIterator : public XMLNodeIteratorBase,
00306 public std::iterator<std::input_iterator_tag, ENTRYTYPE> {
00307 public:
00314 XMLNodeIterator(std::istream &input,
00315 const std::string &baseUrl,
00316 const char *validationPath = 0)
00317 : XMLNodeIteratorBase(input, baseUrl, validationPath), _current(0)
00318 {
00319
00320
00321
00322 }
00323
00324
00332 XMLNodeIterator(ENTRYTYPE &entry)
00333 : XMLNodeIteratorBase()
00334 {
00335 setCurrent((void *)& entry);
00336 }
00337
00343 XMLNodeIterator()
00344 : XMLNodeIteratorBase(), _current(0)
00345 { }
00346
00350 virtual ~XMLNodeIterator()
00351 { }
00352
00357 ENTRYTYPE &
00358 operator*() const
00359 {
00360 assert (! atEnd());
00361 return * (ENTRYTYPE *) getCurrent();
00362 }
00363
00368 ENTRYTYPE *
00369 operator()() const
00370 {
00371 if (_error)
00372 return 0;
00373 else
00374 return getCurrent();
00375 }
00376
00381 XMLNodeIterator<ENTRYTYPE> &
00382 operator++() {
00383 fetchNext();
00384 return *this;
00385 }
00386
00394 XMLNodeIterator operator++(int)
00395 {
00396 assert (!atEnd());
00397 XMLNodeIterator<ENTRYTYPE> tmp(operator()());
00398 fetchNext();
00399 return tmp;
00400 }
00401
00406 const ENTRYTYPE *
00407 operator->()
00408 {
00409 assert(! atEnd());
00410 return getCurrent();
00411 }
00412
00413 protected:
00414
00426 virtual bool
00427 isInterested(const xmlNodePtr nodePtr) = 0;
00428
00443 virtual ENTRYTYPE
00444 process(const xmlTextReaderPtr readerPtr) = 0;
00445
00446 void
00447 _process(const xmlTextReaderPtr readerPtr)
00448 {
00449 setCurrent(new ENTRYTYPE(process(readerPtr)));
00450 }
00451
00452 private:
00453
00454 void setCurrent(const void *data)
00455 {
00456 if (data)
00457 _current.reset(new ENTRYTYPE(* (ENTRYTYPE *) data));
00458 else
00459 _current.reset(0);
00460 }
00461
00462 void *getCurrent() const
00463 {
00464 return _current.get();
00465 }
00466
00473 std::auto_ptr<ENTRYTYPE> _current;
00474 };
00475
00476
00477 #endif