[Lemon-commits] [lemon_svn] alpar: r2262 - hugo/trunk/gui

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:51:20 CET 2006


Author: alpar
Date: Mon Oct 24 10:11:21 2005
New Revision: 2262

Modified:
   hugo/trunk/gui/xml.h

Log:
New version of XML reader/writer.
Now, there are only a single XmlIo class both for reading and writing.

Modified: hugo/trunk/gui/xml.h
==============================================================================
--- hugo/trunk/gui/xml.h	(original)
+++ hugo/trunk/gui/xml.h	Mon Oct 24 10:11:21 2005
@@ -1,4 +1,18 @@
-/* -*- C++ -*- */
+/* -*- C++ -*-
+ * gui/xml.h - Part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
 
 #include <iostream>
 #include <string>
@@ -10,11 +24,18 @@
 
 namespace lemon {
 
-  class XmlWriter 
+  class XmlIo 
   {
+    bool _writeMode;
+  public:
+    ///Check if XmlIo is in write mode.
+    bool write() { return _writeMode;}
+    ///Check if XmlIo is in read mode.
+    bool read() { return !_writeMode;}
+
     std::ostream& os;
     int level;
-
+    
   protected:
     void indent(int level) {
       os << std::endl;
@@ -39,387 +60,343 @@
     }
 
   public:
+    ///Indent the line according to its level.
 
-    void indent() 
+    ///\warning It can only be used in write mode.
+    ///
+    void indent()
     {
-      if(level>=0) indent(level);
-      else level=0;
+      if(write())
+	if(level>=0) indent(level);
+	else level=0;
+      else throw LogicError();	
     }
   
-    ///\e
+    ///Read/write a tag
   
-    ///\e
-    ///
+    ///Read/write a tag.
+    ///In write mode it does not start a new line.
     class ContTag
     {
-      XmlWriter &ix;
+      XmlIo &ix;
       const std::string _tag;
     public:
       ///\e
   
       ///\e
       ///
-      ContTag(XmlWriter &_ix,const std::string &_t) :
+      ContTag(XmlIo &_ix,const std::string &_t) :
 	ix(_ix), _tag(_t)
       {
-	ix.tag(_tag);
+	if(ix.write()) ix.tag(_tag);
+	else ix.useTag(_tag);
+      }
+      ~ContTag() { 
+	if(ix.write()) ix.etag(_tag);
+	else if(!std::uncaught_exception()) ix.useTag('/'+_tag);      
       }
-      ~ContTag() { ix.etag(_tag);}
     };
 
+    ///Read/write a tag
+  
+    ///Read/write a tag.
+    ///The whole <foo> ... </foo> will be places in a single line.
     class LineTag
     {
-      XmlWriter &ix;
+      XmlIo &ix;
       const std::string _tag;
     public:
       ///\e
     
       ///\e
       ///
-      LineTag(XmlWriter &_ix,const std::string &_t) :
+      LineTag(XmlIo &_ix,const std::string &_t) :
 	ix(_ix), _tag(_t)
       {
-	ix.itag(_tag);
+	if(ix.write()) ix.itag(_tag);
+	else ix.useTag(_tag);
+      }
+      ~LineTag() { 
+	if(ix.write()) ix.etag(_tag);
+	else if(!std::uncaught_exception()) ix.useTag('/'+_tag);
       }
-      ~LineTag() { ix.etag(_tag);}
     };
 
-    ///\e
+    ///Read/write a tag
   
-    ///\e
+    ///Read/write a tag.
     ///
     class Tag
     {
-      XmlWriter &ix;
+      XmlIo &ix;
       const std::string _tag;
     public:
       ///\e
   
       ///\e
       ///
-      Tag(XmlWriter &_ix,const std::string &_t) :
+      Tag(XmlIo &_ix,const std::string &_t) :
 	ix(_ix), _tag(_t)
       {
-	ix.beginTag(_tag);
+	if(ix.write()) ix.beginTag(_tag);
+	else ix.useTag(_tag);
       }
-      ~Tag() { 
-	ix.endTag(_tag);
+      ~Tag() {
+	if(ix.write()) ix.endTag(_tag);
+	else if(!std::uncaught_exception()) ix.useTag('/'+_tag);
       }
     };
-      
-    ///\e
-  
-    ///\e
-    ///
-    XmlWriter(std::ostream& _os) : os(_os),level(-1) {}
-    ~XmlWriter() { os<< std::endl; }
-  
-    XmlWriter &operator()(int v) 
-    { 
-      os << v;
-      return *this;
-    }
-    XmlWriter &operator()(const std::string &_tag,int v) 
-    { 
-      LineTag t(*this,_tag);
-      (*this)(v);
-      return *this;
-    }
-    XmlWriter &operator()(double v) 
-    {
-      os << v;
-      return *this;
-    }
-    XmlWriter &operator()(const std::string &_tag,double v) 
-    {
-      LineTag t(*this,_tag);
-      (*this)(v);
-      return *this;
-    }
-    XmlWriter &operator()(const std::string &v)
-    {
-      for(std::string::const_iterator i=v.begin();i!=v.end();++i)
-	switch(*i) {
-	case '\\':
-	  os << "\\\\";
-	  break;
-	case '<':
-	  os << "\\<";
-	  break;
-	case '&':
-	  os << "\\&";
-	  break;
-	case '\n':
-	  os << "\\n";
-	  break;
-	default:
-	  os<<*i;
-	  break;
-	}
-      return *this;
-    }
-    XmlWriter &operator()(const std::string &_tag,const std::string &v)
-    {
-      LineTag t(*this,_tag);
-      (*this)(v);
-      return *this;
-    }
-    ///\e
-  
-    ///\e
-    ///
-    template<class V>
-    XmlWriter &operator()(const std::string &_tag,const V &v)
-    {
-      Tag t(*this,_tag);
-      out(*this,v);
-      return *this;
-    }
-    ///\e
-  
-    ///\e
-    ///
-    template<class V>
-    XmlWriter &operator()(const V &v)
-    {
-      out(*this,v);
-      return *this;
-    }
-  };
 
-  //////////////////////////////////////////////////////////////////////
-
-  class XmlReader 
-  {
+  private:
     std::istream& is;
     std::string next_tag;
     int line_number;
 
     void skipWhiteSpaces()
     {
-      char c;
-      while (is.get(c) && std::isspace(c,is.getloc())) if(c=='\n') line_number++;
-      is.unget();
+      if(write()) throw LogicError();
+      {
+	char c;
+	while (is.get(c) && std::isspace(c,is.getloc()))
+	  if(c=='\n') line_number++;
+	is.unget();
+      }
     }
   protected:
-    ///\e
-  
+    /// Use the next tag.
+
     ///\e
     ///
     void useTag() {next_tag.clear();}
   
+    ///Use the next tag and check if it is equal with \c _tag
+  
+    ///\e
+    ///
     void useTag(const std::string &_tag) {
       if(nextTag()==_tag) useTag();
       else throw DataFormatError("",line_number,"Unexpected token name");
     }
   public:
-    ///\e
+    ///Return the next tag (if a tag follows on the stream).
   
-    ///\e
+    ///\warning It can only be used in read mode.
     ///
     const std::string &nextTag() 
     {
-      if(next_tag.empty()) {
+      if(write()) throw LogicError();
+      else if(next_tag.empty()) {
 	char c;
 	skipWhiteSpaces();
 	if(!is.get(c) || c!='<')
-	  throw DataFormatError("",line_number,"Bad token");
+	  throw DataFormatError("",line_number,"Bad format");
 	next_tag.clear();
 	while (is.get(c) && c!='>') next_tag.push_back(c);
 	if(c!='>')
-	  throw DataFormatError("",line_number,"Bad token");
+	  throw DataFormatError("",line_number,"Bad format");
       }
       return next_tag;
     }
-  
+
+    /**********************************************************************/
+
+
     ///\e
   
     ///\e
     ///
-    class Tag
-    {
-      XmlReader &ix;
-      const std::string tag;
-    public:
-      ///\e
-    
-      ///\e
-      ///
-      Tag(XmlReader &_ix,const std::string &_tag) :
-	ix(_ix), tag(_tag)
-      {
-	ix.useTag(_tag);
-      }
-      ~Tag() {
-	if(!std::uncaught_exception()) 
-	  ix.useTag('/'+tag);
-      }
-    };
-
-    ///\e
-  
+    XmlIo(std::ostream& _os) : _writeMode(true), os(_os),
+			       level(-1),
+			       is(*(std::istream*)(NULL)) {}
     ///\e
     ///
-    XmlReader(std::istream& _is) : is(_is), line_number(1) {}
+    XmlIo(std::istream& _is) : _writeMode(false),
+			       os(*(std::ostream*)(NULL)), is(_is),
+			       line_number(1) {}
+
+    ~XmlIo() { if(write()) os<< std::endl; }
   
-    int operator()(const std::string &tag,int &v)
+
+
+    XmlIo &operator()(const int &v) 
     { 
-      Tag t(*this,tag);
-      skipWhiteSpaces();
-      if(!(is >> v)) throw DataFormatError("",line_number,"Not an 'int'");
-      return v;
-    }
-    double operator()(const std::string &tag,double &v) 
-    {
-      Tag t(*this,tag);
-      skipWhiteSpaces();
-      if(!(is >> v))
-	throw DataFormatError("",line_number,"Not a 'double'");
-      return v;
+      if(write()) os << v;
+      else {
+	skipWhiteSpaces();
+	if(!(is >> const_cast<int &>(v))) 
+	  throw DataFormatError("",line_number,"Not an 'int'");
+      }
+      return *this;
     }
-    std::string &operator()(const std::string &tag,std::string &v)
+    XmlIo &operator()(const double &v) 
     {
-      Tag t(*this,tag);
-      v.clear();
-      char c;
-      while (is.get(c) && c!='<')
-	if(c=='\\')
-	  if(!is.get(c))
-	    throw DataFormatError("",line_number,"Bad string");
-	  else switch(c) {
-	  case 'n':
-	    v.push_back('\n');
+      if(write()) os << v;
+      else {
+	skipWhiteSpaces();
+	if(!(is >> const_cast<double &>(v))) 
+	  throw DataFormatError("",line_number,"Not an 'double'");
+      }
+      return *this;
+    }
+    XmlIo &operator()(const std::string &v)
+    {
+      if(write())
+	for(std::string::const_iterator i=v.begin();i!=v.end();++i)
+	  switch(*i) {
+	  case '\\':
+	    os << "\\\\";
+	    break;
+	  case '<':
+	    os << "\\<";
+	    break;
+	  case '&':
+	    os << "\\&";
+	    break;
+	  case '\n':
+	    os << "\\n";
 	    break;
 	  default:
-	    v.push_back(c);
+	    os<<*i;
 	    break;
 	  }
-	else {
-	  if(c=='\n') line_number++;
-	  v.push_back(c);
-	}
-      if(c!='<')
-	throw DataFormatError("",line_number,"Unexpected eof");
-      is.unget();
-      return v;
+      else {
+	std::string &w = const_cast<std::string &>(v);
+	w.clear();
+	char c;
+	while (is.get(c) && c!='<')
+	  if(c=='\\')
+	    if(!is.get(c))
+	      throw DataFormatError("",line_number,"Bad string");
+	    else switch(c) {
+	    case 'n':
+	      w.push_back('\n');
+	      break;
+	    default:
+	      w.push_back(c);
+	      break;
+	    }
+	  else {
+	    if(c=='\n') line_number++;
+	    w.push_back(c);
+	  }
+	if(c!='<')
+	  throw DataFormatError("",line_number,"Unexpected eof");
+	is.unget();
+      }
+      return *this;
     }
-    ///\e
-  
-    ///\e
-    ///
-    template<class V>
-    V &operator()(const std::string &tag,V &v)
+
+
+    XmlIo &operator()(const std::string &_tag,const int &v) 
+    { 
+      LineTag t(*this,_tag);
+      (*this)(v);
+      return *this;
+    }
+    XmlIo &operator()(const std::string &_tag,const double &v) 
+    {
+      LineTag t(*this,_tag);
+      (*this)(v);
+      return *this;
+    }
+    XmlIo &operator()(const std::string &_tag,const std::string &v)
     {
-      Tag t(*this,tag);
-      in(*this,v);
-      return v;
+      LineTag t(*this,_tag);
+      (*this)(v);
+      return *this;
     }
     ///\e
   
     ///\e
     ///
     template<class V>
-    V &operator()(V &v)
+    XmlIo &operator()(const std::string &_tag,const V &v)
     {
-      in(*this,v);
-      return v;
+      Tag t(*this,_tag);
+      xml(*this,const_cast<V &>(v));
+      return *this;
     }
     ///\e
   
     ///\e
     ///
     template<class V>
-    V load(const std::string &tag)
+    XmlIo &operator()(const V &v)
     {
-      Tag t(*this,tag);
-      V v;
-      (*this)(tag,v);
-      return v;
+      xml(*this,const_cast<V &>(v));
+      return *this;
     }
-  };
+    };
 
   //////////////////////////////////////////////////////////////////////
+  //////////////////////////////////////////////////////////////////////
 
+  ///\e
+  
+  ///\relates XmlIo
+  ///
   template<class A>
-  void out(XmlWriter &x,const std::auto_ptr<A> &v)
-  {
-    x(*v);
-  }
-
-  template<class A>
-  void in(XmlReader &x,std::auto_ptr<A> &v)
+  void xml(XmlIo &x,std::auto_ptr<A> &v)
   {
-    v=new A;
+    if(x.write()) v=new A;
     x(*v);
   }
-
-  //////////////////////////////
-
-  template<class A,class B>
-  void out(XmlWriter &x,const std::pair<A,B> &v)
-  {
-    x("first",v.first);
-    x("second",v.second);
-  }
-
+  
+  ///\e
+  
+  ///\relates XmlIo
+  ///
   template<class A,class B>
-  void in(XmlReader &x,std::pair<A,B> &v)
+  void xml(XmlIo &x,std::pair<A,B> &v)
   {
     x("first",v.first);
     x("second",v.second);
   }
 
-  //////////////////////////////
-
-  template<class T>
-  void out(XmlWriter &x,const std::list<T> &v)
-  {
-    for(typename std::list<T>::const_iterator it=v.begin();
-	it!=v.end();++it) x("item",*it);
-  }
-
+  ///\e
+  
+  ///\relates XmlIo
+  ///
   template<class T>
-  void in(XmlReader &x,std::list<T> &v)
+  void xml(XmlIo &x,std::list<T> &v)
   {
-    while(x.nextTag()=="item")
+    if(x.write())
+      for(typename std::list<T>::const_iterator it=v.begin();
+	  it!=v.end();++it) x("item",*it);
+    else while(x.nextTag()=="item")
       {
 	v.push_back(T());
 	x("item",v.back());
       }
   }
-
-  //////////////////////////////
-
-  template<class T>
-  void out(XmlWriter &x,const std::vector<T> &v)
-  {
-    for(typename std::vector<T>::const_iterator it=v.begin();
-	it!=v.end();++it) x("item",*it);
-  }
-
+  ///\e
+  
+  ///\relates XmlIo
+  ///
   template<class T>
-  void in(XmlReader &x,std::vector<T> &v)
+  void xml(XmlIo &x,std::vector<T> &v)
   {
-    while(x.nextTag()=="item")
+    if(x.write())
+      for(typename std::vector<T>::const_iterator it=v.begin();
+	  it!=v.end();++it) x("item",*it);
+    else while(x.nextTag()=="item")
       {
 	v.push_back(T());
 	x("item",v.back());      
       }
   }
 
-  //////////////////////////////
-
-  template<class K,class V>
-  void out(XmlWriter &x,const std::map<K,V> &v)
-  {
-    for(typename std::map<K,V>::const_iterator it=v.begin();
-	it!=v.end();++it) x("item",*it);
-  }
-
+  ///\e
+  
+  ///\relates XmlIo
+  ///
   template<class K,class V>
-  void in(XmlReader &x,std::map<K,V> &v)
+  void xml(XmlIo &x,std::map<K,V> &v)
   {
-    while(x.nextTag()=="item")
+    if(x.write()) 
+      for(typename std::map<K,V>::const_iterator it=v.begin();
+	  it!=v.end();++it) x("item",*it);
+    else while(x.nextTag()=="item")
       {
 	typename std::map<K,V>::value_type it;
 	x("item",it);
@@ -427,44 +404,39 @@
       }
   }
 
-  //////////////////////////////
-
-  template<class T>
-  void out(XmlWriter &x,const lemon::xy<T> &v)
-  {
-    //   x("x",v.x);
-    //   x("y",v.y);
-    { XmlWriter::LineTag t(x,"x"); x(v.x); }
-    { XmlWriter::ContTag t(x,"y"); x(v.y); }
-  }
-
+  ///\e
+  
+  ///\relates XmlIo
+  ///
   template<class T>
-  void in(XmlReader &x,lemon::xy<T> &v)
+  void xml(XmlIo &x,lemon::xy<T> &v)
   {
-    x("x",v.x);
-    x("y",v.y);
+    { XmlIo::LineTag t(x,"x"); x(v.x); }
+    { XmlIo::ContTag t(x,"y"); x(v.y); }
   }
 
-  //////////////////////////////
-
+  ///\e
+  
+  ///\relates XmlIo
+  ///
   template<class T>
-  void out(XmlWriter &x,const lemon::BoundingBox<T> &v)
+  void xml(XmlIo &x,lemon::BoundingBox<T> &v)
   {
-    if(!v.empty()) {
-      x("point",v.bottomLeft());
-      if(v.bottomLeft()!=v.topRight()) x("point",v.topRight());
+    if(x.write()) {
+      if(!v.empty()) {
+	x("point",v.bottomLeft());
+	if(v.bottomLeft()!=v.topRight()) x("point",v.topRight());
+      }
     }
-  }
-
-  template<class T>
-  void in(XmlReader &x,lemon::BoundingBox<T> &v)
-  {
-    v.clear();
-    while(x.nextTag()=="point") {
-      lemon::xy<T> co;
-      x("point",co);
-      v.add(co);
+    else {
+      v.clear();
+      while(x.nextTag()=="point") {
+	lemon::xy<T> co;
+	x("point",co);
+	v.add(co);
+      }
     }
   }
   
 }
+



More information about the Lemon-commits mailing list