[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