SVN revision 3500 made compilable with Lemon 1.0.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
27 #include <lemon/error.h>
28 #include <lemon/dim2.h>
36 ///Check if XmlIo is in write mode.
37 bool write() { return _writeMode;}
38 ///Check if XmlIo is in read mode.
39 bool read() { return !_writeMode;}
45 void indent(int level) {
47 for(int i=0;i<level;i++) os << ' ';
49 void tag(const std::string &_tag) {
50 os << '<' << _tag << '>';
52 void etag(const std::string &_tag) {
53 os << "</" << _tag << '>';
55 void itag(const std::string &_tag) { indent();tag(_tag); }
56 void ietag(const std::string &_tag) { indent();etag(_tag); }
58 void beginTag(const std::string &_tag) {
62 void endTag(const std::string &_tag) {
68 ///Indent the line according to its level.
70 ///\warning It can only be used in write mode.
75 if(level>=0) indent(level);
77 else throw LogicError();
83 ///In write mode it does not start a new line.
87 const std::string _tag;
93 ContTag(XmlIo &_ix,const std::string &_t) :
96 if(ix.write()) ix.tag(_tag);
100 if(ix.write()) ix.etag(_tag);
101 else if(!std::uncaught_exception()) ix.useTag('/'+_tag);
108 ///The whole \<foo\> ... \</foo\> will be placed in a single line.
112 const std::string _tag;
118 LineTag(XmlIo &_ix,const std::string &_t) :
121 if(ix.write()) ix.itag(_tag);
122 else ix.useTag(_tag);
125 if(ix.write()) ix.etag(_tag);
126 else if(!std::uncaught_exception()) ix.useTag('/'+_tag);
137 const std::string _tag;
143 Tag(XmlIo &_ix,const std::string &_t) :
146 if(ix.write()) ix.beginTag(_tag);
147 else ix.useTag(_tag);
150 if(ix.write()) ix.endTag(_tag);
151 else if(!std::uncaught_exception()) ix.useTag('/'+_tag);
157 std::string next_tag;
160 void skipWhiteSpaces()
162 if(write()) throw LogicError();
165 while (is.get(c) && std::isspace(c,is.getloc()))
166 if(c=='\n') line_number++;
171 /// Use the next tag.
175 void useTag() {next_tag.clear();}
177 ///Use the next tag and check if it is equal with \c _tag
181 void useTag(const std::string &_tag) {
182 if(nextTag()==_tag) useTag();
183 else throw DataFormatError("",line_number,"Unexpected token name");
186 ///Return the next tag (if a tag follows on the stream).
188 ///\warning It can only be used in read mode.
190 const std::string &nextTag()
192 if(write()) throw LogicError();
193 else if(next_tag.empty()) {
196 if(!is.get(c) || c!='<')
197 throw DataFormatError("",line_number,"Bad format");
199 while (is.get(c) && c!='>') next_tag.push_back(c);
201 throw DataFormatError("",line_number,"Bad format");
206 /**********************************************************************/
213 XmlIo(std::ostream& _os) : _writeMode(true), os(_os),
218 XmlIo(std::istream& _is) : _writeMode(false),
219 os(std::cout), is(_is),
222 ~XmlIo() { if(write()) os<< std::endl; }
226 XmlIo &operator()(const int &v)
231 if(!(is >> const_cast<int &>(v)))
232 throw DataFormatError("",line_number,"Not an 'int'");
236 XmlIo &operator()(const double &v)
241 if(!(is >> const_cast<double &>(v)))
242 throw DataFormatError("",line_number,"Not an 'double'");
246 XmlIo &operator()(const std::string &v)
249 for(std::string::const_iterator i=v.begin();i!=v.end();++i)
268 std::string &w = const_cast<std::string &>(v);
271 while (is.get(c) && c!='<')
274 throw DataFormatError("",line_number,"Bad string");
284 if(c=='\n') line_number++;
288 throw DataFormatError("",line_number,"Unexpected eof");
295 XmlIo &operator()(const std::string &_tag,const int &v)
297 LineTag t(*this,_tag);
301 XmlIo &operator()(const std::string &_tag,const double &v)
303 LineTag t(*this,_tag);
307 XmlIo &operator()(const std::string &_tag,const std::string &v)
309 LineTag t(*this,_tag);
318 XmlIo &operator()(const std::string &_tag,const V &v)
321 xml(*this,const_cast<V &>(v));
329 XmlIo &operator()(const V &v)
331 xml(*this,const_cast<V &>(v));
336 //////////////////////////////////////////////////////////////////////
337 //////////////////////////////////////////////////////////////////////
344 void xml(XmlIo &x,std::auto_ptr<A> &v)
346 if(x.write()) v=new A;
354 template<class A,class B>
355 void xml(XmlIo &x,std::pair<A,B> &v)
358 x("second",v.second);
366 void xml(XmlIo &x,std::list<T> &v)
369 for(typename std::list<T>::const_iterator it=v.begin();
370 it!=v.end();++it) x("item",*it);
371 else while(x.nextTag()=="item")
382 void xml(XmlIo &x,std::vector<T> &v)
385 for(typename std::vector<T>::const_iterator it=v.begin();
386 it!=v.end();++it) x("item",*it);
387 else while(x.nextTag()=="item")
398 template<class K,class V>
399 void xml(XmlIo &x,std::map<K,V> &v)
402 for(typename std::map<K,V>::const_iterator it=v.begin();
403 it!=v.end();++it) x("item",*it);
404 else while(x.nextTag()=="item")
406 typename std::map<K,V>::value_type it;
417 void xml(XmlIo &x,lemon::dim2::Point<T> &v)
419 { XmlIo::LineTag t(x,"x"); x(v.x); }
420 { XmlIo::ContTag t(x,"y"); x(v.y); }
428 void xml(XmlIo &x,lemon::dim2::BoundingBox<T> &v)
432 x("point",v.bottomLeft());
433 if(v.bottomLeft()!=v.topRight()) x("point",v.topRight());
438 while(x.nextTag()=="point") {
439 lemon::dim2::Point<T> co;