Removed this extra widget thing, because it is now developed in my private branch.
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
24 #include <lemon/error.h>
25 #include <lemon/dim2.h>
33 ///Check if XmlIo is in write mode.
34 bool write() { return _writeMode;}
35 ///Check if XmlIo is in read mode.
36 bool read() { return !_writeMode;}
42 void indent(int level) {
44 for(int i=0;i<level;i++) os << ' ';
46 void tag(const std::string &_tag) {
47 os << '<' << _tag << '>';
49 void etag(const std::string &_tag) {
50 os << "</" << _tag << '>';
52 void itag(const std::string &_tag) { indent();tag(_tag); }
53 void ietag(const std::string &_tag) { indent();etag(_tag); }
55 void beginTag(const std::string &_tag) {
59 void endTag(const std::string &_tag) {
65 ///Indent the line according to its level.
67 ///\warning It can only be used in write mode.
72 if(level>=0) indent(level);
74 else throw LogicError();
80 ///In write mode it does not start a new line.
84 const std::string _tag;
90 ContTag(XmlIo &_ix,const std::string &_t) :
93 if(ix.write()) ix.tag(_tag);
97 if(ix.write()) ix.etag(_tag);
98 else if(!std::uncaught_exception()) ix.useTag('/'+_tag);
105 ///The whole \<foo\> ... \</foo\> will be placed in a single line.
109 const std::string _tag;
115 LineTag(XmlIo &_ix,const std::string &_t) :
118 if(ix.write()) ix.itag(_tag);
119 else ix.useTag(_tag);
122 if(ix.write()) ix.etag(_tag);
123 else if(!std::uncaught_exception()) ix.useTag('/'+_tag);
134 const std::string _tag;
140 Tag(XmlIo &_ix,const std::string &_t) :
143 if(ix.write()) ix.beginTag(_tag);
144 else ix.useTag(_tag);
147 if(ix.write()) ix.endTag(_tag);
148 else if(!std::uncaught_exception()) ix.useTag('/'+_tag);
154 std::string next_tag;
157 void skipWhiteSpaces()
159 if(write()) throw LogicError();
162 while (is.get(c) && std::isspace(c,is.getloc()))
163 if(c=='\n') line_number++;
168 /// Use the next tag.
172 void useTag() {next_tag.clear();}
174 ///Use the next tag and check if it is equal with \c _tag
178 void useTag(const std::string &_tag) {
179 if(nextTag()==_tag) useTag();
180 else throw DataFormatError("",line_number,"Unexpected token name");
183 ///Return the next tag (if a tag follows on the stream).
185 ///\warning It can only be used in read mode.
187 const std::string &nextTag()
189 if(write()) throw LogicError();
190 else if(next_tag.empty()) {
193 if(!is.get(c) || c!='<')
194 throw DataFormatError("",line_number,"Bad format");
196 while (is.get(c) && c!='>') next_tag.push_back(c);
198 throw DataFormatError("",line_number,"Bad format");
203 /**********************************************************************/
210 XmlIo(std::ostream& _os) : _writeMode(true), os(_os),
215 XmlIo(std::istream& _is) : _writeMode(false),
216 os(std::cout), is(_is),
219 ~XmlIo() { if(write()) os<< std::endl; }
223 XmlIo &operator()(const int &v)
228 if(!(is >> const_cast<int &>(v)))
229 throw DataFormatError("",line_number,"Not an 'int'");
233 XmlIo &operator()(const double &v)
238 if(!(is >> const_cast<double &>(v)))
239 throw DataFormatError("",line_number,"Not an 'double'");
243 XmlIo &operator()(const std::string &v)
246 for(std::string::const_iterator i=v.begin();i!=v.end();++i)
265 std::string &w = const_cast<std::string &>(v);
268 while (is.get(c) && c!='<')
271 throw DataFormatError("",line_number,"Bad string");
281 if(c=='\n') line_number++;
285 throw DataFormatError("",line_number,"Unexpected eof");
292 XmlIo &operator()(const std::string &_tag,const int &v)
294 LineTag t(*this,_tag);
298 XmlIo &operator()(const std::string &_tag,const double &v)
300 LineTag t(*this,_tag);
304 XmlIo &operator()(const std::string &_tag,const std::string &v)
306 LineTag t(*this,_tag);
315 XmlIo &operator()(const std::string &_tag,const V &v)
318 xml(*this,const_cast<V &>(v));
326 XmlIo &operator()(const V &v)
328 xml(*this,const_cast<V &>(v));
333 //////////////////////////////////////////////////////////////////////
334 //////////////////////////////////////////////////////////////////////
341 void xml(XmlIo &x,std::auto_ptr<A> &v)
343 if(x.write()) v=new A;
351 template<class A,class B>
352 void xml(XmlIo &x,std::pair<A,B> &v)
355 x("second",v.second);
363 void xml(XmlIo &x,std::list<T> &v)
366 for(typename std::list<T>::const_iterator it=v.begin();
367 it!=v.end();++it) x("item",*it);
368 else while(x.nextTag()=="item")
379 void xml(XmlIo &x,std::vector<T> &v)
382 for(typename std::vector<T>::const_iterator it=v.begin();
383 it!=v.end();++it) x("item",*it);
384 else while(x.nextTag()=="item")
395 template<class K,class V>
396 void xml(XmlIo &x,std::map<K,V> &v)
399 for(typename std::map<K,V>::const_iterator it=v.begin();
400 it!=v.end();++it) x("item",*it);
401 else while(x.nextTag()=="item")
403 typename std::map<K,V>::value_type it;
414 void xml(XmlIo &x,lemon::dim2::Point<T> &v)
416 { XmlIo::LineTag t(x,"x"); x(v.x); }
417 { XmlIo::ContTag t(x,"y"); x(v.y); }
425 void xml(XmlIo &x,lemon::dim2::BoundingBox<T> &v)
429 x("point",v.bottomLeft());
430 if(v.bottomLeft()!=v.topRight()) x("point",v.topRight());
435 while(x.nextTag()=="point") {
436 lemon::dim2::Point<T> co;