Changeset 83:6c0db51a1d99 in glemon-0.x
- Timestamp:
- 10/24/05 10:11:21 (19 years ago)
- Branch:
- gui
- Phase:
- public
- Convert:
- svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk/gui@2262
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
xml.h
r39 r83 1 /* -*- C++ -*- */ 1 /* -*- C++ -*- 2 * gui/xml.h - Part of LEMON, a generic C++ optimization library 3 * 4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 5 * (Egervary Research Group on Combinatorial Optimization, EGRES). 6 * 7 * Permission to use, modify and distribute this software is granted 8 * provided that this copyright notice appears in all copies. For 9 * precise terms see the accompanying LICENSE file. 10 * 11 * This software is provided "AS IS" with no warranty of any kind, 12 * express or implied, and with no claim as to its suitability for any 13 * purpose. 14 * 15 */ 2 16 3 17 #include <iostream> … … 11 25 namespace lemon { 12 26 13 class XmlWriter 14 { 27 class XmlIo 28 { 29 bool _writeMode; 30 public: 31 ///Check if XmlIo is in write mode. 32 bool write() { return _writeMode;} 33 ///Check if XmlIo is in read mode. 34 bool read() { return !_writeMode;} 35 15 36 std::ostream& os; 16 37 int level; 17 38 18 39 protected: 19 40 void indent(int level) { … … 40 61 41 62 public: 42 43 void indent() 44 { 45 if(level>=0) indent(level); 46 else level=0; 47 } 48 49 ///\e 50 51 ///\e 52 /// 63 ///Indent the line according to its level. 64 65 ///\warning It can only be used in write mode. 66 /// 67 void indent() 68 { 69 if(write()) 70 if(level>=0) indent(level); 71 else level=0; 72 else throw LogicError(); 73 } 74 75 ///Read/write a tag 76 77 ///Read/write a tag. 78 ///In write mode it does not start a new line. 53 79 class ContTag 54 80 { 55 Xml Writer&ix;81 XmlIo &ix; 56 82 const std::string _tag; 57 83 public: … … 60 86 ///\e 61 87 /// 62 ContTag(Xml Writer&_ix,const std::string &_t) :88 ContTag(XmlIo &_ix,const std::string &_t) : 63 89 ix(_ix), _tag(_t) 64 90 { 65 ix.tag(_tag); 66 } 67 ~ContTag() { ix.etag(_tag);} 91 if(ix.write()) ix.tag(_tag); 92 else ix.useTag(_tag); 93 } 94 ~ContTag() { 95 if(ix.write()) ix.etag(_tag); 96 else if(!std::uncaught_exception()) ix.useTag('/'+_tag); 97 } 68 98 }; 69 99 100 ///Read/write a tag 101 102 ///Read/write a tag. 103 ///The whole <foo> ... </foo> will be places in a single line. 70 104 class LineTag 71 105 { 72 Xml Writer&ix;106 XmlIo &ix; 73 107 const std::string _tag; 74 108 public: … … 77 111 ///\e 78 112 /// 79 LineTag(Xml Writer&_ix,const std::string &_t) :113 LineTag(XmlIo &_ix,const std::string &_t) : 80 114 ix(_ix), _tag(_t) 81 115 { 82 ix.itag(_tag); 83 } 84 ~LineTag() { ix.etag(_tag);} 116 if(ix.write()) ix.itag(_tag); 117 else ix.useTag(_tag); 118 } 119 ~LineTag() { 120 if(ix.write()) ix.etag(_tag); 121 else if(!std::uncaught_exception()) ix.useTag('/'+_tag); 122 } 85 123 }; 86 124 87 /// \e88 89 /// \e125 ///Read/write a tag 126 127 ///Read/write a tag. 90 128 /// 91 129 class Tag 92 130 { 93 Xml Writer&ix;131 XmlIo &ix; 94 132 const std::string _tag; 95 133 public: … … 98 136 ///\e 99 137 /// 100 Tag(Xml Writer&_ix,const std::string &_t) :138 Tag(XmlIo &_ix,const std::string &_t) : 101 139 ix(_ix), _tag(_t) 102 140 { 103 ix.beginTag(_tag); 104 } 105 ~Tag() { 106 ix.endTag(_tag); 141 if(ix.write()) ix.beginTag(_tag); 142 else ix.useTag(_tag); 143 } 144 ~Tag() { 145 if(ix.write()) ix.endTag(_tag); 146 else if(!std::uncaught_exception()) ix.useTag('/'+_tag); 107 147 } 108 148 }; 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) 149 150 private: 151 std::istream& is; 152 std::string next_tag; 153 int line_number; 154 155 void skipWhiteSpaces() 156 { 157 if(write()) throw LogicError(); 158 { 159 char c; 160 while (is.get(c) && std::isspace(c,is.getloc())) 161 if(c=='\n') line_number++; 162 is.unget(); 163 } 164 } 165 protected: 166 /// Use the next tag. 167 168 ///\e 169 /// 170 void useTag() {next_tag.clear();} 171 172 ///Use the next tag and check if it is equal with \c _tag 173 174 ///\e 175 /// 176 void useTag(const std::string &_tag) { 177 if(nextTag()==_tag) useTag(); 178 else throw DataFormatError("",line_number,"Unexpected token name"); 179 } 180 public: 181 ///Return the next tag (if a tag follows on the stream). 182 183 ///\warning It can only be used in read mode. 184 /// 185 const std::string &nextTag() 186 { 187 if(write()) throw LogicError(); 188 else if(next_tag.empty()) { 189 char c; 190 skipWhiteSpaces(); 191 if(!is.get(c) || c!='<') 192 throw DataFormatError("",line_number,"Bad format"); 193 next_tag.clear(); 194 while (is.get(c) && c!='>') next_tag.push_back(c); 195 if(c!='>') 196 throw DataFormatError("",line_number,"Bad format"); 197 } 198 return next_tag; 199 } 200 201 /**********************************************************************/ 202 203 204 ///\e 205 206 ///\e 207 /// 208 XmlIo(std::ostream& _os) : _writeMode(true), os(_os), 209 level(-1), 210 is(*(std::istream*)(NULL)) {} 211 ///\e 212 /// 213 XmlIo(std::istream& _is) : _writeMode(false), 214 os(*(std::ostream*)(NULL)), is(_is), 215 line_number(1) {} 216 217 ~XmlIo() { if(write()) os<< std::endl; } 218 219 220 221 XmlIo &operator()(const int &v) 118 222 { 119 os << v; 120 return *this; 121 } 122 XmlWriter &operator()(const std::string &_tag,int v) 223 if(write()) os << v; 224 else { 225 skipWhiteSpaces(); 226 if(!(is >> const_cast<int &>(v))) 227 throw DataFormatError("",line_number,"Not an 'int'"); 228 } 229 return *this; 230 } 231 XmlIo &operator()(const double &v) 232 { 233 if(write()) os << v; 234 else { 235 skipWhiteSpaces(); 236 if(!(is >> const_cast<double &>(v))) 237 throw DataFormatError("",line_number,"Not an 'double'"); 238 } 239 return *this; 240 } 241 XmlIo &operator()(const std::string &v) 242 { 243 if(write()) 244 for(std::string::const_iterator i=v.begin();i!=v.end();++i) 245 switch(*i) { 246 case '\\': 247 os << "\\\\"; 248 break; 249 case '<': 250 os << "\\<"; 251 break; 252 case '&': 253 os << "\\&"; 254 break; 255 case '\n': 256 os << "\\n"; 257 break; 258 default: 259 os<<*i; 260 break; 261 } 262 else { 263 std::string &w = const_cast<std::string &>(v); 264 w.clear(); 265 char c; 266 while (is.get(c) && c!='<') 267 if(c=='\\') 268 if(!is.get(c)) 269 throw DataFormatError("",line_number,"Bad string"); 270 else switch(c) { 271 case 'n': 272 w.push_back('\n'); 273 break; 274 default: 275 w.push_back(c); 276 break; 277 } 278 else { 279 if(c=='\n') line_number++; 280 w.push_back(c); 281 } 282 if(c!='<') 283 throw DataFormatError("",line_number,"Unexpected eof"); 284 is.unget(); 285 } 286 return *this; 287 } 288 289 290 XmlIo &operator()(const std::string &_tag,const int &v) 123 291 { 124 292 LineTag t(*this,_tag); … … 126 294 return *this; 127 295 } 128 XmlWriter &operator()(double v) 129 { 130 os << v; 131 return *this; 132 } 133 XmlWriter &operator()(const std::string &_tag,double v) 296 XmlIo &operator()(const std::string &_tag,const double &v) 134 297 { 135 298 LineTag t(*this,_tag); … … 137 300 return *this; 138 301 } 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) 302 XmlIo &operator()(const std::string &_tag,const std::string &v) 162 303 { 163 304 LineTag t(*this,_tag); … … 170 311 /// 171 312 template<class V> 172 Xml Writer&operator()(const std::string &_tag,const V &v)313 XmlIo &operator()(const std::string &_tag,const V &v) 173 314 { 174 315 Tag t(*this,_tag); 175 out(*this,v);316 xml(*this,const_cast<V &>(v)); 176 317 return *this; 177 318 } … … 181 322 /// 182 323 template<class V> 183 Xml Writer&operator()(const V &v)184 { 185 out(*this,v);186 return *this; 187 } 188 };324 XmlIo &operator()(const V &v) 325 { 326 xml(*this,const_cast<V &>(v)); 327 return *this; 328 } 329 }; 189 330 190 331 ////////////////////////////////////////////////////////////////////// 191 192 class XmlReader193 {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 ///\e206 207 ///\e208 ///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 ///\e217 218 ///\e219 ///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 ///\e236 237 ///\e238 ///239 class Tag240 {241 XmlReader &ix;242 const std::string tag;243 public:244 ///\e245 246 ///\e247 ///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 ///\e260 261 ///\e262 ///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 ///\e307 308 ///\e309 ///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 ///\e318 319 ///\e320 ///321 template<class V>322 V &operator()(V &v)323 {324 in(*this,v);325 return v;326 }327 ///\e328 329 ///\e330 ///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 332 ////////////////////////////////////////////////////////////////////// 342 333 334 ///\e 335 336 ///\relates XmlIo 337 /// 343 338 template<class A> 344 void out(XmlWriter &x,const std::auto_ptr<A> &v) 345 { 339 void xml(XmlIo &x,std::auto_ptr<A> &v) 340 { 341 if(x.write()) v=new A; 346 342 x(*v); 347 343 } 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 344 345 ///\e 346 347 ///\relates XmlIo 348 /// 358 349 template<class A,class B> 359 void out(XmlWriter &x,conststd::pair<A,B> &v)350 void xml(XmlIo &x,std::pair<A,B> &v) 360 351 { 361 352 x("first",v.first); … … 363 354 } 364 355 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 356 ///\e 357 358 ///\relates XmlIo 359 /// 374 360 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") 361 void xml(XmlIo &x,std::list<T> &v) 362 { 363 if(x.write()) 364 for(typename std::list<T>::const_iterator it=v.begin(); 365 it!=v.end();++it) x("item",*it); 366 else while(x.nextTag()=="item") 385 367 { 386 368 v.push_back(T()); … … 388 370 } 389 371 } 390 391 ////////////////////////////// 392 372 ///\e 373 374 ///\relates XmlIo 375 /// 393 376 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") 377 void xml(XmlIo &x,std::vector<T> &v) 378 { 379 if(x.write()) 380 for(typename std::vector<T>::const_iterator it=v.begin(); 381 it!=v.end();++it) x("item",*it); 382 else while(x.nextTag()=="item") 404 383 { 405 384 v.push_back(T()); … … 408 387 } 409 388 410 ////////////////////////////// 411 389 ///\e 390 391 ///\relates XmlIo 392 /// 412 393 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") 394 void xml(XmlIo &x,std::map<K,V> &v) 395 { 396 if(x.write()) 397 for(typename std::map<K,V>::const_iterator it=v.begin(); 398 it!=v.end();++it) x("item",*it); 399 else while(x.nextTag()=="item") 423 400 { 424 401 typename std::map<K,V>::value_type it; … … 428 405 } 429 406 430 ////////////////////////////// 431 407 ///\e 408 409 ///\relates XmlIo 410 /// 432 411 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 412 void xml(XmlIo &x,lemon::xy<T> &v) 413 { 414 { XmlIo::LineTag t(x,"x"); x(v.x); } 415 { XmlIo::ContTag t(x,"y"); x(v.y); } 416 } 417 418 ///\e 419 420 ///\relates XmlIo 421 /// 441 422 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); 423 void xml(XmlIo &x,lemon::BoundingBox<T> &v) 424 { 425 if(x.write()) { 426 if(!v.empty()) { 427 x("point",v.bottomLeft()); 428 if(v.bottomLeft()!=v.topRight()) x("point",v.topRight()); 429 } 430 } 431 else { 432 v.clear(); 433 while(x.nextTag()=="point") { 434 lemon::xy<T> co; 435 x("point",co); 436 v.add(co); 437 } 467 438 } 468 439 } 469 440 470 441 } 442
Note: See TracChangeset
for help on using the changeset viewer.