Accept but ignore special tags: <!, <?; Start of class UnsingedInteger; success: make distcheck
This commit is contained in:
		| @@ -46,12 +46,13 @@ namespace xml { | ||||
|       iterator _active; | ||||
|   }; | ||||
|   typedef Attributes::Value Attr; | ||||
|   enum NodeType {START, END, EMPTY}; | ||||
|   enum NodeType {START, END, EMPTY, SPECIAL}; | ||||
|   struct Tag { | ||||
|       std::string name; | ||||
|       NodeType type; | ||||
|       std::string text; | ||||
|       Attributes attributes; | ||||
|       std::string special; | ||||
|   }; | ||||
|   const bool mandatory = true; | ||||
|   const bool optional = false; | ||||
| @@ -82,6 +83,13 @@ namespace xml { | ||||
|           exception("tag ('<') expected, text not allowed\ntext: "+txt, t) {} | ||||
|   }; | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class type_mismatch: public exception { | ||||
|     public: | ||||
|       type_mismatch(const Node& t, const std::string& txt) throw(): | ||||
|           exception("wrong type, text contains mismatching character\ntext: " | ||||
|                     +txt, t) {} | ||||
|   }; | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class access_error: public exception { | ||||
|     public: | ||||
|       access_error(const Node& t, const std::string& name) throw(); | ||||
| @@ -204,7 +212,8 @@ namespace xml { | ||||
|       virtual std::ostream& out(std::ostream& o, unsigned int level=0) const | ||||
|           throw(); | ||||
|       virtual std::string text() const throw(); | ||||
|       virtual Node& text(const std::string& txt) throw(tag_expected); | ||||
|       virtual Node& text(const std::string& txt) throw(tag_expected, | ||||
|                                                        type_mismatch); | ||||
|       virtual Node& append(const Node& o) throw(cannot_have_children); | ||||
|       virtual Node& set(const Attributes& o) throw(); | ||||
|       Node& clear() throw (); | ||||
| @@ -230,7 +239,8 @@ namespace xml { | ||||
|       //! Get the first named child. | ||||
|       Node& operator[](const std::string& child) throw(access_error); | ||||
|       std::string operator*() const throw(); | ||||
|       Node& operator=(const std::string& contents) throw(tag_expected); | ||||
|       Node& operator=(const std::string& contents) throw(tag_expected, | ||||
|                                                          type_mismatch); | ||||
|       friend std::ostream& operator<<(std::ostream& o, const Node& t) throw(); | ||||
|     protected: | ||||
|       Attributes _attributes; | ||||
| @@ -250,7 +260,25 @@ namespace xml { | ||||
|       virtual std::auto_ptr<Node> clone() const throw(); | ||||
|       virtual ~String() throw() {} | ||||
|       virtual std::string text() const throw(); | ||||
|       virtual String& text(const std::string& txt) throw(tag_expected); | ||||
|       virtual String& text(const std::string& txt) throw(tag_expected, | ||||
|                                                          type_mismatch); | ||||
|       virtual std::ostream& out(std::ostream& o, unsigned int level=0) const | ||||
|           throw(); | ||||
|       virtual String& append(const Node& o) throw(cannot_have_children); | ||||
|       Node& operator=(const std::string& contents) throw(); | ||||
|     private: | ||||
|       std::string _text; | ||||
|   }; | ||||
|  | ||||
|   //---------------------------------------------------------------------------- | ||||
|   class UnsignedInteger: public Node { | ||||
|     public: | ||||
|       String(std::string name, const std::string& text = std::string()) throw(); | ||||
|       virtual std::auto_ptr<Node> clone() const throw(); | ||||
|       virtual ~String() throw() {} | ||||
|       virtual std::string text() const throw(); | ||||
|       virtual String& text(const std::string& txt) throw(tag_expected, | ||||
|                                                          type_mismatch); | ||||
|       virtual std::ostream& out(std::ostream& o, unsigned int level=0) const | ||||
|           throw(); | ||||
|       virtual String& append(const Node& o) throw(cannot_have_children); | ||||
| @@ -268,7 +296,7 @@ namespace xml { | ||||
|       Factory(const Node& t) throw(); | ||||
|       const Node& operator*() const throw(); | ||||
|       std::auto_ptr<Node> read(std::istream& is) | ||||
|           throw(wrong_end_tag, wrong_start_tag, tag_expected, | ||||
|           throw(wrong_end_tag, wrong_start_tag, tag_expected, type_mismatch, | ||||
|                 second_slash_in_tag, character_after_slash, | ||||
|                 missing_end_tag, attribute_value_not_quoted, access_error, | ||||
|                 empty_stream, duplicate_attribute, attributes_in_end_tag); | ||||
| @@ -278,7 +306,7 @@ namespace xml { | ||||
|       Factory(const Factory&); // not implemented | ||||
|       bool ws(char c) const throw(); | ||||
|       std::auto_ptr<Node> read(std::istream& is, const Node& position) | ||||
|           throw(wrong_end_tag, wrong_start_tag, tag_expected, | ||||
|           throw(wrong_end_tag, wrong_start_tag, tag_expected, type_mismatch, | ||||
|                 second_slash_in_tag, character_after_slash, | ||||
|                 missing_end_tag, | ||||
|                 attribute_value_not_quoted, access_error, duplicate_attribute, | ||||
|   | ||||
							
								
								
									
										67
									
								
								src/xml.cxx
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								src/xml.cxx
									
									
									
									
									
								
							| @@ -200,7 +200,7 @@ namespace xml { | ||||
|       s+=***it; | ||||
|     return s; | ||||
|   } | ||||
|   Node& Node::text(const std::string& txt) throw(tag_expected) { | ||||
|   Node& Node::text(const std::string& txt) throw(tag_expected, type_mismatch) { | ||||
|     throw tag_expected(*this, txt); | ||||
|   } | ||||
|   Node& Node::append(const Node& o) throw(cannot_have_children) { | ||||
| @@ -281,7 +281,8 @@ namespace xml { | ||||
|   std::string Node::operator*() const throw() { | ||||
|     return text(); | ||||
|   } | ||||
|   Node& Node::operator=(const std::string& contents) throw(tag_expected) { | ||||
|   Node& Node::operator=(const std::string& contents) throw(tag_expected, | ||||
|                                                            type_mismatch) { | ||||
|     return text(contents); | ||||
|   } | ||||
|   std::ostream& operator<<(std::ostream& o, const Node& t) throw() { | ||||
| @@ -310,7 +311,8 @@ namespace xml { | ||||
|   std::string String::text() const throw() { | ||||
|     return _text; | ||||
|   } | ||||
|   String& String::text(const std::string& txt) throw(tag_expected) { | ||||
|   String& String::text(const std::string& txt) throw(tag_expected, | ||||
|                                                      type_mismatch) { | ||||
|     _text = txt; | ||||
|     return *this; | ||||
|   } | ||||
| @@ -337,13 +339,52 @@ namespace xml { | ||||
|     return text(contents); | ||||
|   } | ||||
|  | ||||
|   //---------------------------------------------------------------------------- | ||||
|   UnsingedInteger::UnsingedInteger(std::string name, const std::string& text) throw(): | ||||
|       Node(name), _text(text) { | ||||
|   } | ||||
|   std::auto_ptr<Node> UnsingedInteger::clone() const throw() { | ||||
|     return std::auto_ptr<Node>(new UnsingedInteger(*this)); | ||||
|   } | ||||
|   std::string UnsingedInteger::text() const throw() { | ||||
|     return _text; | ||||
|   } | ||||
|   UnsingedInteger& UnsingedInteger::text(const std::string& txt) throw(tag_expected, | ||||
|                                                      type_mismatch) { | ||||
|     _text = txt; | ||||
|     return *this; | ||||
|   } | ||||
|   std::ostream& UnsingedInteger::out(std::ostream& o, unsigned int level) const throw() { | ||||
|     if (_text.size()) { | ||||
|       o<<std::string(level, '\t')<<'<'<<name(); | ||||
|       for (Attributes::const_iterator it(_attributes.begin()); | ||||
|            it!=_attributes.end(); ++it) | ||||
|         o<<' '<<it->first<<"=\""<<it->second<<'"'; | ||||
|       o<<'>'<<_text<<"</"<<name()<<'>'; | ||||
|     } else { | ||||
|       o<<std::string(level, '\t')<<'<'<<name(); | ||||
|       for (Attributes::const_iterator it(_attributes.begin()); | ||||
|            it!=_attributes.end(); ++it) | ||||
|         o<<' '<<it->first<<"=\""<<it->second<<'"'; | ||||
|       o<<"/>"; | ||||
|     } | ||||
|     return o; | ||||
|   } | ||||
|   UnsingedInteger& UnsingedInteger::append(const Node& o) throw(cannot_have_children) { | ||||
|     throw cannot_have_children(*this, o); | ||||
|   } | ||||
|   Node& UnsingedInteger::operator=(const std::string& contents) throw() { | ||||
|     return text(contents); | ||||
|   } | ||||
|  | ||||
|   //---------------------------------------------------------------------------- | ||||
|   Factory::Factory(const Node& t) throw(): _template(t.clone()) {} | ||||
|   const Node& Factory::operator*() const throw() { | ||||
|     return *_template; | ||||
|   } | ||||
|   std::auto_ptr<Node> Factory::read(std::istream& is) | ||||
|       throw(wrong_end_tag, wrong_start_tag, tag_expected, second_slash_in_tag, | ||||
|       throw(wrong_end_tag, wrong_start_tag, tag_expected, type_mismatch, | ||||
|             second_slash_in_tag, | ||||
|             character_after_slash, missing_end_tag, attribute_value_not_quoted, | ||||
|             access_error, empty_stream, duplicate_attribute, | ||||
|             attributes_in_end_tag) { | ||||
| @@ -356,18 +397,19 @@ namespace xml { | ||||
|       throw empty_stream(*node, is, res); | ||||
|     } | ||||
|     *node<<res.attributes; | ||||
|     switch (res.type) { | ||||
|     while (true) switch (res.type) { | ||||
|       case END: throw wrong_end_tag(*node, is, res); | ||||
|       case EMPTY: return node; // empty | ||||
|       case START: return read(is, *_template); | ||||
|       case SPECIAL: break; //! @todo ignored could be stored | ||||
|     } | ||||
|     abort(); // coding error: should not reach here | ||||
|   } | ||||
|   bool Factory::ws(char c) const throw() { | ||||
|     return c==' '||c=='\t'||c=='\n'||c=='\r'; | ||||
|   } | ||||
|   std::auto_ptr<Node> Factory::read(std::istream& is, const Node& node) | ||||
|       throw(wrong_end_tag, wrong_start_tag, tag_expected, second_slash_in_tag, | ||||
|       throw(wrong_end_tag, wrong_start_tag, tag_expected, type_mismatch, | ||||
|             second_slash_in_tag, | ||||
|             character_after_slash, missing_end_tag, attribute_value_not_quoted, | ||||
|             access_error, duplicate_attribute, attributes_in_end_tag) { | ||||
|     std::auto_ptr<Node> result(node.clone()); | ||||
| @@ -387,6 +429,7 @@ namespace xml { | ||||
|         case START: { | ||||
|           *result<<(*read(is, node[res.name])<<res.attributes); | ||||
|         } break; | ||||
|         case SPECIAL: break; //! @todo ignored could be stored | ||||
|       } | ||||
|     } | ||||
|     return result; | ||||
| @@ -401,8 +444,7 @@ namespace xml { | ||||
|     if (!is) throw missing_end_tag(position, is, tag); | ||||
|     if (c!='<') do tag.text+=c; while (is && is.get(c) && c!='<'); | ||||
|     bool nameRead(false); | ||||
|     while (is && is.get(c) && c!='>') { | ||||
|       switch (c) { | ||||
|     for (char last(c); is && is.get(c) && c!='>'; last = c) switch (c) { | ||||
|       case ' ': case '\t': case '\n': case '\r': | ||||
|         if (!nameRead && tag.name.size()) nameRead=true; | ||||
|         break; | ||||
| @@ -411,6 +453,11 @@ namespace xml { | ||||
|         if (tag.type!=START) throw second_slash_in_tag(position, is, tag, c); | ||||
|         tag.type = nameRead?EMPTY:END; | ||||
|         break; | ||||
|       case '!': case '?': | ||||
|         if (last=='<') { // <! tag or <?xml.. starts | ||||
|           do tag.special+=c; while (c!='>' && is && is.get(c)); | ||||
|           return tag; | ||||
|         } | ||||
|       default: | ||||
|         if (tag.type==EMPTY) throw character_after_slash(position, is, tag, c); | ||||
|         if (nameRead) { // read attribute | ||||
| @@ -431,7 +478,7 @@ namespace xml { | ||||
|         } else { // part of a tag name | ||||
|           tag.name+=c; | ||||
|         } | ||||
|       }} | ||||
|     } | ||||
|     return tag; | ||||
|   } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user