tbx  0.7.3
tag.h
1 /*
2  * tbx RISC OS toolbox library
3  *
4  * Copyright (C) 2010 Alan Buckley All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 #ifndef TBX_TAG_H_
26 #define TBX_TAG_H_
27 
28 #include <vector>
29 #include <string>
30 #include <iostream>
31 #include <stdexcept>
32 #include <cstdlib>
33 
34 namespace tbx
35 {
36 
37 class TagDoc;
38 class Tag;
39 
44 {
45 protected:
46  TagAttribute(int id);
47  TagAttribute(int id, const std::string &value);
48  ~TagAttribute();
49 
50 public:
54  int id() const {return _id;}
55 
59  const std::string &value() {return _value;}
65  int integer() const {return atoi(_value.c_str());}
71  void value(const std::string &value) {_value = value;_has_value = true;}
72 
78  void has_value(bool has) {_has_value = has;}
84  bool has_value() const {return _has_value;}
85 
91  TagAttribute *next() {return _next;}
92 
93 protected:
94  int _id;
95  std::string _value;
96  bool _has_value;
98 
99  // Tag class maintains the attributes
100  friend class Tag;
101 };
102 
106 class TagData
107 {
108 public:
109  TagData() {};
110  virtual ~TagData() {};
111 };
112 
123 class Tag
124 {
125 protected:
126  Tag(Tag *parent, int id);
127  ~Tag();
128 
129 public:
135  int id() const {return _id;}
136  const std::string &name() const;
137 
138  TagDoc *doc() const;
144  Tag *parent() const {return _parent;}
145 
151  Tag *first_child() const {return _first_child;}
157  Tag *last_child() const {return _last_child;}
163  Tag *next() const {return _next;}
164 
171 
172  Tag *add_child(int id);
173  Tag *add_child(const std::string &name);
174  void delete_child(Tag *tag);
175 
176  Tag *find_child(int id, Tag *after = NULL) const;
177  Tag *find_child(const std::string &name, Tag *after = NULL) const;
178  Tag *find_child(int id, int attId, Tag *after = NULL) const;
179  Tag *find_child(const std::string &name, const std::string &attName, Tag *after = NULL) const;
180  Tag *find_child(int id, int attId, const std::string &value, Tag *after = NULL) const;
181  Tag *find_child(const std::string &name, const std::string &attName, const std::string &value, Tag *after = NULL) const;
182 
188  const std::string &text() const {return _text;}
194  void text(const std::string &text) {_text = text;}
195 
201  TagData *data() const {return _data;}
207  void data(TagData *data) {_data = data;}
208 
209  void attribute(int att_id);
210  void attribute(int att_id, const std::string &value);
211  void delete_attribute(int attId);
212 
213  void attribute(const std::string &name);
214  void attribute(const std::string &name, const std::string &value);
215  void delete_attribute(const std::string &name);
216 
217  TagAttribute *find_attribute(int att_id) const;
218  TagAttribute *find_attribute(const std::string &name) const;
219 
220  std::string attribute_value(int att_id) const;
221  std::string attribute_value(const std::string &name) const;
222 
223 protected:
229 
230  int _id;
231  std::string _text;
233 };
234 
244 class TagDoc : public Tag
245 {
246 public:
247  TagDoc();
248  ~TagDoc();
249 
250  int tag_id(const std::string &name);
251  const std::string &tag_name(int id) const;
252  int tag_id_if_exists(const std::string &name) const;
253 
254  int attribute_id(const std::string &name);
255  int attribute_id_if_exists(const std::string &name) const;
256  const std::string &attribute_name(int id) const;
257 
258  void write_tag(std::ostream &os, Tag *tag, int indent = 0);
259  void read_tag(std::istream &is);
260 
261 protected:
262  // Helper functions
263  void write_string(std::ostream &os, const std::string &text);
264  char read_string(std::istream &is, std::string &text);
265  char read_name(std::istream &is, std::string &name);
266 
267 protected:
271  std::vector<std::string> _tag_names;
275  std::vector<std::string> _attribute_names;
276 };
277 
278 
282 class TagException : public std::runtime_error
283 {
284 public:
288  enum Cause {None, EmptyFile, ErrorReading, EndTagNotMatch,
289  InvalidTagStartChar, InvalidTagEndChar,
290  InvalidNameEnd, MissingTagName,
291  InvalidStringStart, InvalidStringEnd, InvalidEntityEnd, InvalidEntity
292  };
293  TagException(Cause cause, const std::string &item);
294  TagException(Cause cause, char c);
295  ~TagException() throw() {}
296 
300  Cause cause() const {return _cause;}
301 
305  const std::string &item() const {return _item;}
306 
307 private:
308  static std::string error_text(Cause cause, std::string item);
309 // Member variables
310 private:
311  Cause _cause;
312  std::string _item;
313 };
314 
315 };
316 
317 std::istream &operator>>(std::istream &is, tbx::TagDoc &doc);
318 std::ostream &operator<<(std::ostream &os, tbx::TagDoc &doc);
319 
320 
321 #endif
void write_string(std::ostream &os, const std::string &text)
Write a string to the output stream converting characters used in the syntax to special entities...
Definition: tag.cc:774
TagData * _data
user data or 0 if none
Definition: tag.h:232
Exception thrown when reading a saved tag fails.
Definition: tag.h:282
~Tag()
Destructor for tag deletes assosiated tag data.
Definition: tag.cc:109
Tag * find_child(int id, Tag *after=NULL) const
Find the a child tag with the given id.
Definition: tag.cc:195
void attribute(int att_id)
Sets attribute with given id on the tag with no value.
Definition: tag.cc:320
Tag * parent() const
Get the parent for this tag.
Definition: tag.h:144
Cause cause() const
Return enumeration value specifying the cause of the exception.
Definition: tag.h:300
char read_name(std::istream &is, std::string &name)
Read a name from and input stream.
Definition: tag.cc:855
Document that stores Tags with optional attributes in a hierarchy.
Definition: tag.h:244
void data(TagData *data)
Set the data for this tag.
Definition: tag.h:207
int tag_id(const std::string &name)
Returns the tag id for a name or allocates a new one if the name has not already been used...
Definition: tag.cc:484
char read_string(std::istream &is, std::string &text)
Read a string from an input stream converting entities used back to characters.
Definition: tag.cc:807
const std::string & attribute_name(int id) const
Get the name of the attribute given its id.
Definition: tag.cc:581
void text(const std::string &text)
Set the text for this tag.
Definition: tag.h:194
bool _has_value
true if attribute has a value
Definition: tag.h:96
std::string _text
text for this type of tag or "" if not set
Definition: tag.h:231
TagAttribute * next()
Get the next attribute for the same tag.
Definition: tag.h:91
int attribute_id(const std::string &name)
Returns the attribute id for a name or allocates a new one if the name has not already been used...
Definition: tag.cc:538
Base class used for adding data to a tag.
Definition: tag.h:106
const std::string & tag_name(int id) const
Get the name of the tag given its id.
Definition: tag.cc:527
TagAttribute(int id)
Construct an attribute without a value.
Definition: tag.cc:62
TagData * data() const
Get the user data for this tag.
Definition: tag.h:201
TagAttribute * first_attribute() const
Get the first attribute of this tag.
Definition: tag.h:170
TagAttribute * _next
Next attribute for the same tag.
Definition: tag.h:97
const std::string & name() const
Return the name of this type of tag.
Definition: tag.cc:118
Tag * _parent
parent tag or 0 for no parent
Definition: tag.h:224
int _id
ID for this type of tag.
Definition: tag.h:230
const std::string & value()
Get the current string value for the attribute.
Definition: tag.h:59
TagAttribute * find_attribute(int att_id) const
Find the attribute with the given id.
Definition: tag.cc:421
Cause
Enumeration describing the reason for a tag exception.
Definition: tag.h:288
void delete_attribute(int attId)
Delete the attribute with the given id.
Definition: tag.cc:357
Tag * _first_child
first child tag or 0 for no children
Definition: tag.h:225
TagAttribute * _first_attribute
first attribute or 0 if no attributes
Definition: tag.h:228
int id() const
Return the tag id.
Definition: tag.h:135
TagException(Cause cause, const std::string &item)
Constructor for error with an item name.
Definition: tag.cc:878
void write_tag(std::ostream &os, Tag *tag, int indent=0)
Write a tag and all its children to an output stream.
Definition: tag.cc:721
int integer() const
Return the current value as an integer.
Definition: tag.h:65
Class to represent a some data tagged with an id.
Definition: tag.h:123
bool has_value() const
Check if the attribute has a value.
Definition: tag.h:84
TagDoc * doc() const
Return the document this tag belongs to.
Definition: tag.cc:126
Tag * _last_child
last child tag or 0 for no children
Definition: tag.h:226
void read_tag(std::istream &is)
Reads a tag and all its children from a stream.
Definition: tag.cc:611
int _id
Id of attribute.
Definition: tag.h:94
Tag(Tag *parent, int id)
Construct a tag with the given parent and id.
Definition: tag.cc:94
void delete_child(Tag *tag)
Deletes at child tag.
Definition: tag.cc:171
TagDoc()
Constructor for a new empty tag document.
Definition: tag.cc:467
std::vector< std::string > _attribute_names
List of all attribute names known to this document.
Definition: tag.h:275
std::vector< std::string > _tag_names
List of all tag names known to this document.
Definition: tag.h:271
int attribute_id_if_exists(const std::string &name) const
Gets a attribute id if it has already been defined.
Definition: tag.cc:563
Tag * next() const
Get the next sibling tag.
Definition: tag.h:163
int tag_id_if_exists(const std::string &name) const
Gets a tag id if it has already been defined.
Definition: tag.cc:509
void has_value(bool has)
Set if the attribute has a value associated with it.
Definition: tag.h:78
int id() const
Attribute Id.
Definition: tag.h:54
const std::string & text() const
Get the text from the tag.
Definition: tag.h:188
Tag * add_child(int id)
Add a new tag as a child of this tag.
Definition: tag.cc:139
Tag * last_child() const
Get the last child tag.
Definition: tag.h:157
~TagDoc()
Destructor.
Definition: tag.cc:474
void value(const std::string &value)
Set the value of the attribute.
Definition: tag.h:71
Class to represent a single attribute.
Definition: tag.h:43
Tag * _next
next sibling tag or 0 if no more siblings
Definition: tag.h:227
Tag * first_child() const
Get the first child tag.
Definition: tag.h:151
std::string _value
Value of attribute (if any)
Definition: tag.h:95
std::string attribute_value(int att_id) const
Get the value of an attribute.
Definition: tag.cc:446
const std::string & item() const
Return the item or character the exception happened on.
Definition: tag.h:305