xml.h
changeset 7 f227a74db59d
parent 1 67188bd752db
equal deleted inserted replaced
0:eeaea25b06d9 1:47224482bd6f
    23 #include <string>
    23 #include <string>
    24 #include <vector>
    24 #include <vector>
    25 #include <list>
    25 #include <list>
    26 #include <map>
    26 #include <map>
    27 #include <lemon/error.h>
    27 #include <lemon/error.h>
       
    28 #include <lemon/assert.h>
    28 #include <lemon/dim2.h>
    29 #include <lemon/dim2.h>
    29 
    30 
    30 namespace lemon {
    31 namespace lemon {
    31 
    32 
    32   class XmlIo 
    33   class XmlIo 
    72     void indent()
    73     void indent()
    73     {
    74     {
    74       if(write())
    75       if(write())
    75 	if(level>=0) indent(level);
    76 	if(level>=0) indent(level);
    76 	else level=0;
    77 	else level=0;
    77       else throw LogicError();	
    78       else LEMON_ASSERT(true, "Invalid indentation.");	
    78     }
    79     }
    79   
    80   
    80     ///Read/write a tag
    81     ///Read/write a tag
    81   
    82   
    82     ///Read/write a tag.
    83     ///Read/write a tag.
   157     std::string next_tag;
   158     std::string next_tag;
   158     int line_number;
   159     int line_number;
   159 
   160 
   160     void skipWhiteSpaces()
   161     void skipWhiteSpaces()
   161     {
   162     {
   162       if(write()) throw LogicError();
   163       if(write()) LEMON_ASSERT(true, "Can't skip whitespaces in write mode.");
   163       {
   164       {
   164 	char c;
   165 	char c;
   165 	while (is.get(c) && std::isspace(c,is.getloc()))
   166 	while (is.get(c) && std::isspace(c,is.getloc()))
   166 	  if(c=='\n') line_number++;
   167 	  if(c=='\n') line_number++;
   167 	is.unget();
   168 	is.unget();
   178   
   179   
   179     ///\e
   180     ///\e
   180     ///
   181     ///
   181     void useTag(const std::string &_tag) {
   182     void useTag(const std::string &_tag) {
   182       if(nextTag()==_tag) useTag();
   183       if(nextTag()==_tag) useTag();
   183       else throw DataFormatError("",line_number,"Unexpected token name");
   184       else throw FormatError("Unexpected token name","",line_number);
   184     }
   185     }
   185   public:
   186   public:
   186     ///Return the next tag (if a tag follows on the stream).
   187     ///Return the next tag (if a tag follows on the stream).
   187   
   188   
   188     ///\warning It can only be used in read mode.
   189     ///\warning It can only be used in read mode.
   189     ///
   190     ///
   190     const std::string &nextTag() 
   191     const std::string &nextTag() 
   191     {
   192     {
   192       if(write()) throw LogicError();
   193       if(write()) LEMON_ASSERT(true,"Don't use nextTag() in write mode");
   193       else if(next_tag.empty()) {
   194       else if(next_tag.empty()) {
   194 	char c;
   195 	char c;
   195 	skipWhiteSpaces();
   196 	skipWhiteSpaces();
   196 	if(!is.get(c) || c!='<')
   197 	if(!is.get(c) || c!='<')
   197 	  throw DataFormatError("",line_number,"Bad format");
   198 	  throw FormatError("Bad format","",line_number);
   198 	next_tag.clear();
   199 	next_tag.clear();
   199 	while (is.get(c) && c!='>') next_tag.push_back(c);
   200 	while (is.get(c) && c!='>') next_tag.push_back(c);
   200 	if(c!='>')
   201 	if(c!='>')
   201 	  throw DataFormatError("",line_number,"Bad format");
   202 	  throw FormatError("Bad format","",line_number);
   202       }
   203       }
   203       return next_tag;
   204       return next_tag;
   204     }
   205     }
   205 
   206 
   206     /**********************************************************************/
   207     /**********************************************************************/
   227     { 
   228     { 
   228       if(write()) os << v;
   229       if(write()) os << v;
   229       else {
   230       else {
   230 	skipWhiteSpaces();
   231 	skipWhiteSpaces();
   231 	if(!(is >> const_cast<int &>(v))) 
   232 	if(!(is >> const_cast<int &>(v))) 
   232 	  throw DataFormatError("",line_number,"Not an 'int'");
   233 	  throw FormatError("Not an 'int'","",line_number);
   233       }
   234       }
   234       return *this;
   235       return *this;
   235     }
   236     }
   236     XmlIo &operator()(const double &v) 
   237     XmlIo &operator()(const double &v) 
   237     {
   238     {
   238       if(write()) os << v;
   239       if(write()) os << v;
   239       else {
   240       else {
   240 	skipWhiteSpaces();
   241 	skipWhiteSpaces();
   241 	if(!(is >> const_cast<double &>(v))) 
   242 	if(!(is >> const_cast<double &>(v))) 
   242 	  throw DataFormatError("",line_number,"Not an 'double'");
   243 	  throw FormatError("Not an 'double'","",line_number);
   243       }
   244       }
   244       return *this;
   245       return *this;
   245     }
   246     }
   246     XmlIo &operator()(const std::string &v)
   247     XmlIo &operator()(const std::string &v)
   247     {
   248     {
   269 	w.clear();
   270 	w.clear();
   270 	char c;
   271 	char c;
   271 	while (is.get(c) && c!='<')
   272 	while (is.get(c) && c!='<')
   272 	  if(c=='\\')
   273 	  if(c=='\\')
   273 	    if(!is.get(c))
   274 	    if(!is.get(c))
   274 	      throw DataFormatError("",line_number,"Bad string");
   275 	      throw FormatError("Bad string","",line_number);
   275 	    else switch(c) {
   276 	    else switch(c) {
   276 	    case 'n':
   277 	    case 'n':
   277 	      w.push_back('\n');
   278 	      w.push_back('\n');
   278 	      break;
   279 	      break;
   279 	    default:
   280 	    default:
   283 	  else {
   284 	  else {
   284 	    if(c=='\n') line_number++;
   285 	    if(c=='\n') line_number++;
   285 	    w.push_back(c);
   286 	    w.push_back(c);
   286 	  }
   287 	  }
   287 	if(c!='<')
   288 	if(c!='<')
   288 	  throw DataFormatError("",line_number,"Unexpected eof");
   289 	  throw FormatError("Unexpected eof","",line_number);
   289 	is.unget();
   290 	is.unget();
   290       }
   291       }
   291       return *this;
   292       return *this;
   292     }
   293     }
   293 
   294 
   423   ///\e
   424   ///\e
   424   
   425   
   425   ///\relates XmlIo
   426   ///\relates XmlIo
   426   ///
   427   ///
   427   template<class T>
   428   template<class T>
   428   void xml(XmlIo &x,lemon::dim2::BoundingBox<T> &v)
   429   void xml(XmlIo &x,lemon::dim2::Box<T> &v)
   429   {
   430   {
   430     if(x.write()) {
   431     if(x.write()) {
   431       if(!v.empty()) {
   432       if(!v.empty()) {
   432 	x("point",v.bottomLeft());
   433 	x("point",v.bottomLeft());
   433 	if(v.bottomLeft()!=v.topRight()) x("point",v.topRight());
   434 	if(v.bottomLeft()!=v.topRight()) x("point",v.topRight());