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 { |