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