There were bugs, created yesterday, and there is still one. (I hope only one :) )
16 void indent(int level) {
18 for(int i=0;i<level;i++) os << ' ';
20 void tag(const std::string &_tag) {
21 os << '<' << _tag << '>';
23 void etag(const std::string &_tag) {
24 os << "</" << _tag << '>';
26 void itag(const std::string &_tag) { indent();tag(_tag); }
27 void ietag(const std::string &_tag) { indent();etag(_tag); }
29 void beginTag(const std::string &_tag) {
33 void endTag(const std::string &_tag) {
42 if(level>=0) indent(level);
53 const std::string _tag;
59 ContTag(XmlWriter &_ix,const std::string &_t) :
64 ~ContTag() { ix.etag(_tag);}
70 const std::string _tag;
76 LineTag(XmlWriter &_ix,const std::string &_t) :
81 ~LineTag() { ix.etag(_tag);}
91 const std::string _tag;
97 Tag(XmlWriter &_ix,const std::string &_t) :
111 XmlWriter(std::ostream& _os) : os(_os),level(-1) {}
112 ~XmlWriter() { os<< std::endl; }
114 XmlWriter &operator()(int v)
116 if(!(os << v)) throw (std::ios::failure ("data format error"));
119 XmlWriter &operator()(const std::string &_tag,int v)
121 LineTag t(*this,_tag);
122 if(!(os << v)) throw (std::ios::failure ("data format error"));
125 XmlWriter &operator()(const std::string &_tag,double v)
127 LineTag t(*this,_tag);
128 if(os << v) throw (std::ios::failure ("data format error"));
131 XmlWriter &operator()(double v)
136 XmlWriter &operator()(const std::string &v)
138 for(std::string::const_iterator i=v.begin();i!=v.end();++i)
158 XmlWriter &operator()(const std::string &_tag,const std::string &v)
160 LineTag t(*this,_tag);
169 XmlWriter &operator()(const std::string &_tag,const V &v)
180 XmlWriter &operator()(const V &v)
187 //////////////////////////////////////////////////////////////////////
193 std::string next_tag;
194 void skipWhiteSpaces()
197 while (is.get(c) && std::isspace(c,is.getloc()));
205 void useTag() {next_tag.clear();}
207 void useTag(const std::string &_tag) {
208 if(nextTag()==_tag) useTag();
209 else throw (std::ios::failure ("data format error"));
216 const std::string &nextTag()
218 if(next_tag.empty()) {
221 if(!is.get(c) || c!='<')
222 throw (std::ios::failure ("data format error"));
224 while (is.get(c) && c!='>') next_tag.push_back(c);
226 throw (std::ios::failure ("data format error"));
238 const std::string tag;
244 Tag(XmlReader &_ix,const std::string &_tag) :
250 if(!std::uncaught_exception())
259 XmlReader(std::istream& _is) : is(_is) {}
261 int operator()(const std::string &tag,int &v)
264 if(!(is >> v)) throw (std::ios::failure ("data format error"));
267 double operator()(const std::string &tag,double &v)
270 if(!(is >> v)) throw (std::ios::failure ("data format error"));
273 std::string &operator()(const std::string &tag,std::string &v)
278 while (is.get(c) && c!='<')
280 if(!is.get(c)) throw (std::ios::failure ("data format error"));
291 throw (std::ios::failure ("data format error"));
300 V &operator()(const std::string &tag,V &v)
321 V load(const std::string &tag)
330 //////////////////////////////////////////////////////////////////////
332 template<class A,class B>
333 void out(XmlWriter &i,const std::pair<A,B> &v)
336 i("second",v.second);
339 template<class A,class B>
340 void in(XmlReader &i,std::pair<A,B> &v)
343 i("second",v.second);
346 //////////////////////////////
349 void out(XmlWriter &i,const std::list<T> &v)
351 for(typename std::list<T>::const_iterator it=v.begin();
352 it!=v.end();++it) i("item",*it);
356 void in(XmlReader &i,std::list<T> &v)
358 while(i.nextTag()=="item")
365 //////////////////////////////
368 void out(XmlWriter &i,const std::vector<T> &v)
370 for(typename std::vector<T>::const_iterator it=v.begin();
371 it!=v.end();++it) i("item",*it);
375 void in(XmlReader &i,std::vector<T> &v)
377 while(i.nextTag()=="item")
384 //////////////////////////////
386 template<class K,class V>
387 void out(XmlWriter &i,const std::map<K,V> &v)
389 for(typename std::map<K,V>::const_iterator it=v.begin();
390 it!=v.end();++it) i("item",*it);
393 template<class K,class V>
394 void in(XmlReader &i,std::map<K,V> &v)
396 while(i.nextTag()=="item")
398 typename std::map<K,V>::value_type it;
404 //////////////////////////////
407 void out(XmlWriter &i,const lemon::xy<T> &v)
411 { XmlWriter::LineTag t(i,"x"); i(v.x); }
412 { XmlWriter::ContTag t(i,"y"); i(v.y); }
416 void in(XmlReader &i,lemon::xy<T> &v)
422 //////////////////////////////
425 void out(XmlWriter &i,const lemon::BoundingBox<T> &v)
428 i("point",v.bottomLeft());
429 if(v.bottomLeft()!=v.topRight()) i("point",v.topRight());
434 void in(XmlReader &i,lemon::BoundingBox<T> &v)
437 while(i.nextTag()=="point") {