COIN-OR::LEMON - Graph Library

source: lemon-0.x/gui/xml.h @ 1686:a5b8e0fde2be

Last change on this file since 1686:a5b8e0fde2be was 1588:b79bcba43661, checked in by Alpar Juttner, 19 years ago

BoundingBox?<T>::operator+=() -> BoundingBox?<T>::add() ->

File size: 8.3 KB
Line 
1/* -*- C++ -*- */
2
3#include <iostream>
4#include <string>
5#include <vector>
6#include <list>
7#include <map>
8#include <lemon/error.h>
9#include <lemon/xy.h>
10
11namespace lemon {
12
13  class XmlWriter
14  {
15    std::ostream& os;
16    int level;
17
18  protected:
19    void indent(int level) {
20      os << std::endl;
21      for(int i=0;i<level;i++) os << ' ';
22    }
23    void tag(const std::string &_tag) {
24      os << '<' << _tag << '>';
25    }
26    void etag(const std::string &_tag) {
27      os << "</" << _tag << '>';
28    }
29    void itag(const std::string &_tag) { indent();tag(_tag); }
30    void ietag(const std::string &_tag) { indent();etag(_tag); }
31
32    void beginTag(const std::string &_tag) {
33      itag(_tag);
34      level++;
35    }
36    void endTag(const std::string &_tag) {
37      level--;
38      ietag(_tag);
39    }
40
41  public:
42
43    void indent()
44    {
45      if(level>=0) indent(level);
46      else level=0;
47    }
48 
49    ///\e
50 
51    ///\e
52    ///
53    class ContTag
54    {
55      XmlWriter &ix;
56      const std::string _tag;
57    public:
58      ///\e
59 
60      ///\e
61      ///
62      ContTag(XmlWriter &_ix,const std::string &_t) :
63        ix(_ix), _tag(_t)
64      {
65        ix.tag(_tag);
66      }
67      ~ContTag() { ix.etag(_tag);}
68    };
69
70    class LineTag
71    {
72      XmlWriter &ix;
73      const std::string _tag;
74    public:
75      ///\e
76   
77      ///\e
78      ///
79      LineTag(XmlWriter &_ix,const std::string &_t) :
80        ix(_ix), _tag(_t)
81      {
82        ix.itag(_tag);
83      }
84      ~LineTag() { ix.etag(_tag);}
85    };
86
87    ///\e
88 
89    ///\e
90    ///
91    class Tag
92    {
93      XmlWriter &ix;
94      const std::string _tag;
95    public:
96      ///\e
97 
98      ///\e
99      ///
100      Tag(XmlWriter &_ix,const std::string &_t) :
101        ix(_ix), _tag(_t)
102      {
103        ix.beginTag(_tag);
104      }
105      ~Tag() {
106        ix.endTag(_tag);
107      }
108    };
109     
110    ///\e
111 
112    ///\e
113    ///
114    XmlWriter(std::ostream& _os) : os(_os),level(-1) {}
115    ~XmlWriter() { os<< std::endl; }
116 
117    XmlWriter &operator()(int v)
118    {
119      os << v;
120      return *this;
121    }
122    XmlWriter &operator()(const std::string &_tag,int v)
123    {
124      LineTag t(*this,_tag);
125      (*this)(v);
126      return *this;
127    }
128    XmlWriter &operator()(double v)
129    {
130      os << v;
131      return *this;
132    }
133    XmlWriter &operator()(const std::string &_tag,double v)
134    {
135      LineTag t(*this,_tag);
136      (*this)(v);
137      return *this;
138    }
139    XmlWriter &operator()(const std::string &v)
140    {
141      for(std::string::const_iterator i=v.begin();i!=v.end();++i)
142        switch(*i) {
143        case '\\':
144          os << "\\\\";
145          break;
146        case '<':
147          os << "\\<";
148          break;
149        case '&':
150          os << "\\&";
151          break;
152        case '\n':
153          os << "\\n";
154          break;
155        default:
156          os<<*i;
157          break;
158        }
159      return *this;
160    }
161    XmlWriter &operator()(const std::string &_tag,const std::string &v)
162    {
163      LineTag t(*this,_tag);
164      (*this)(v);
165      return *this;
166    }
167    ///\e
168 
169    ///\e
170    ///
171    template<class V>
172    XmlWriter &operator()(const std::string &_tag,const V &v)
173    {
174      Tag t(*this,_tag);
175      out(*this,v);
176      return *this;
177    }
178    ///\e
179 
180    ///\e
181    ///
182    template<class V>
183    XmlWriter &operator()(const V &v)
184    {
185      out(*this,v);
186      return *this;
187    }
188  };
189
190  //////////////////////////////////////////////////////////////////////
191
192  class XmlReader
193  {
194    std::istream& is;
195    std::string next_tag;
196    int line_number;
197
198    void skipWhiteSpaces()
199    {
200      char c;
201      while (is.get(c) && std::isspace(c,is.getloc())) if(c=='\n') line_number++;
202      is.unget();
203    }
204  protected:
205    ///\e
206 
207    ///\e
208    ///
209    void useTag() {next_tag.clear();}
210 
211    void useTag(const std::string &_tag) {
212      if(nextTag()==_tag) useTag();
213      else throw DataFormatError("",line_number,"Unexpected token name");
214    }
215  public:
216    ///\e
217 
218    ///\e
219    ///
220    const std::string &nextTag()
221    {
222      if(next_tag.empty()) {
223        char c;
224        skipWhiteSpaces();
225        if(!is.get(c) || c!='<')
226          throw DataFormatError("",line_number,"Bad token");
227        next_tag.clear();
228        while (is.get(c) && c!='>') next_tag.push_back(c);
229        if(c!='>')
230          throw DataFormatError("",line_number,"Bad token");
231      }
232      return next_tag;
233    }
234 
235    ///\e
236 
237    ///\e
238    ///
239    class Tag
240    {
241      XmlReader &ix;
242      const std::string tag;
243    public:
244      ///\e
245   
246      ///\e
247      ///
248      Tag(XmlReader &_ix,const std::string &_tag) :
249        ix(_ix), tag(_tag)
250      {
251        ix.useTag(_tag);
252      }
253      ~Tag() {
254        if(!std::uncaught_exception())
255          ix.useTag('/'+tag);
256      }
257    };
258
259    ///\e
260 
261    ///\e
262    ///
263    XmlReader(std::istream& _is) : is(_is), line_number(1) {}
264 
265    int operator()(const std::string &tag,int &v)
266    {
267      Tag t(*this,tag);
268      skipWhiteSpaces();
269      if(!(is >> v)) throw DataFormatError("",line_number,"Not an 'int'");
270      return v;
271    }
272    double operator()(const std::string &tag,double &v)
273    {
274      Tag t(*this,tag);
275      skipWhiteSpaces();
276      if(!(is >> v))
277        throw DataFormatError("",line_number,"Not a 'double'");
278      return v;
279    }
280    std::string &operator()(const std::string &tag,std::string &v)
281    {
282      Tag t(*this,tag);
283      v.clear();
284      char c;
285      while (is.get(c) && c!='<')
286        if(c=='\\')
287          if(!is.get(c))
288            throw DataFormatError("",line_number,"Bad string");
289          else switch(c) {
290          case 'n':
291            v.push_back('\n');
292            break;
293          default:
294            v.push_back(c);
295            break;
296          }
297        else {
298          if(c=='\n') line_number++;
299          v.push_back(c);
300        }
301      if(c!='<')
302        throw DataFormatError("",line_number,"Unexpected eof");
303      is.unget();
304      return v;
305    }
306    ///\e
307 
308    ///\e
309    ///
310    template<class V>
311    V &operator()(const std::string &tag,V &v)
312    {
313      Tag t(*this,tag);
314      in(*this,v);
315      return v;
316    }
317    ///\e
318 
319    ///\e
320    ///
321    template<class V>
322    V &operator()(V &v)
323    {
324      in(*this,v);
325      return v;
326    }
327    ///\e
328 
329    ///\e
330    ///
331    template<class V>
332    V load(const std::string &tag)
333    {
334      Tag t(*this,tag);
335      V v;
336      (*this)(tag,v);
337      return v;
338    }
339  };
340
341  //////////////////////////////////////////////////////////////////////
342
343  template<class A>
344  void out(XmlWriter &x,const std::auto_ptr<A> &v)
345  {
346    x(*v);
347  }
348
349  template<class A>
350  void in(XmlReader &x,std::auto_ptr<A> &v)
351  {
352    v=new A;
353    x(*v);
354  }
355
356  //////////////////////////////
357
358  template<class A,class B>
359  void out(XmlWriter &x,const std::pair<A,B> &v)
360  {
361    x("first",v.first);
362    x("second",v.second);
363  }
364
365  template<class A,class B>
366  void in(XmlReader &x,std::pair<A,B> &v)
367  {
368    x("first",v.first);
369    x("second",v.second);
370  }
371
372  //////////////////////////////
373
374  template<class T>
375  void out(XmlWriter &x,const std::list<T> &v)
376  {
377    for(typename std::list<T>::const_iterator it=v.begin();
378        it!=v.end();++it) x("item",*it);
379  }
380
381  template<class T>
382  void in(XmlReader &x,std::list<T> &v)
383  {
384    while(x.nextTag()=="item")
385      {
386        v.push_back(T());
387        x("item",v.back());
388      }
389  }
390
391  //////////////////////////////
392
393  template<class T>
394  void out(XmlWriter &x,const std::vector<T> &v)
395  {
396    for(typename std::vector<T>::const_iterator it=v.begin();
397        it!=v.end();++it) x("item",*it);
398  }
399
400  template<class T>
401  void in(XmlReader &x,std::vector<T> &v)
402  {
403    while(x.nextTag()=="item")
404      {
405        v.push_back(T());
406        x("item",v.back());     
407      }
408  }
409
410  //////////////////////////////
411
412  template<class K,class V>
413  void out(XmlWriter &x,const std::map<K,V> &v)
414  {
415    for(typename std::map<K,V>::const_iterator it=v.begin();
416        it!=v.end();++it) x("item",*it);
417  }
418
419  template<class K,class V>
420  void in(XmlReader &x,std::map<K,V> &v)
421  {
422    while(x.nextTag()=="item")
423      {
424        typename std::map<K,V>::value_type it;
425        x("item",it);
426        v.insert(it);
427      }
428  }
429
430  //////////////////////////////
431
432  template<class T>
433  void out(XmlWriter &x,const lemon::xy<T> &v)
434  {
435    //   x("x",v.x);
436    //   x("y",v.y);
437    { XmlWriter::LineTag t(x,"x"); x(v.x); }
438    { XmlWriter::ContTag t(x,"y"); x(v.y); }
439  }
440
441  template<class T>
442  void in(XmlReader &x,lemon::xy<T> &v)
443  {
444    x("x",v.x);
445    x("y",v.y);
446  }
447
448  //////////////////////////////
449
450  template<class T>
451  void out(XmlWriter &x,const lemon::BoundingBox<T> &v)
452  {
453    if(!v.empty()) {
454      x("point",v.bottomLeft());
455      if(v.bottomLeft()!=v.topRight()) x("point",v.topRight());
456    }
457  }
458
459  template<class T>
460  void in(XmlReader &x,lemon::BoundingBox<T> &v)
461  {
462    v.clear();
463    while(x.nextTag()=="point") {
464      lemon::xy<T> co;
465      x("point",co);
466      v.add(co);
467    }
468  }
469 
470}
Note: See TracBrowser for help on using the repository browser.