1 | // -------------------------------------------------------------------------------- |
---|
2 | // Copyright (C) 2001 |
---|
3 | // Ralf Westram |
---|
4 | // |
---|
5 | // Permission to use, copy, modify, distribute and sell this software |
---|
6 | // and its documentation for any purpose is hereby granted without fee, |
---|
7 | // provided that the above copyright notice appear in all copies and |
---|
8 | // that both that copyright notice and this permission notice appear |
---|
9 | // in supporting documentation. Ralf Westram makes no |
---|
10 | // representations about the suitability of this software for any |
---|
11 | // purpose. It is provided "as is" without express or implied warranty. |
---|
12 | // |
---|
13 | // This code is part of my library. |
---|
14 | // You may find a more recent version at http://www.reallysoft.de/ |
---|
15 | // -------------------------------------------------------------------------------- |
---|
16 | |
---|
17 | #ifndef XML_HXX |
---|
18 | #define XML_HXX |
---|
19 | |
---|
20 | #ifndef __STRING__ |
---|
21 | #include <string> |
---|
22 | #endif |
---|
23 | #ifndef __CSTDIO__ |
---|
24 | #include <cstdio> |
---|
25 | #endif |
---|
26 | |
---|
27 | #ifndef ATTRIBUTES_H |
---|
28 | #include <attributes.h> |
---|
29 | #endif |
---|
30 | #ifndef ARB_ASSERT_H |
---|
31 | #include <arb_assert.h> |
---|
32 | #endif |
---|
33 | #ifndef ARBTOOLS_H |
---|
34 | #include <arbtools.h> |
---|
35 | #endif |
---|
36 | |
---|
37 | #define xml_assert(bed) arb_assert(bed) |
---|
38 | |
---|
39 | |
---|
40 | /*! @memo Classes used to write xml |
---|
41 | @doc In order to write xml to a stream just open an XML_Document and create and destroy the needed tags. |
---|
42 | */ |
---|
43 | |
---|
44 | class XML_Document; |
---|
45 | extern XML_Document *the_XML_Document; // there can only be one at a time |
---|
46 | |
---|
47 | // ---------------------------- |
---|
48 | // class XML_Attribute |
---|
49 | |
---|
50 | class XML_Attribute FINAL_TYPE : virtual Noncopyable { |
---|
51 | private: |
---|
52 | std::string name; |
---|
53 | std::string content; |
---|
54 | XML_Attribute *next; |
---|
55 | |
---|
56 | public: |
---|
57 | XML_Attribute(const std::string& name_, const std::string& content_); |
---|
58 | virtual ~XML_Attribute(); |
---|
59 | |
---|
60 | XML_Attribute *append_to(XML_Attribute *queue); |
---|
61 | |
---|
62 | void print(FILE *out) const; |
---|
63 | }; |
---|
64 | |
---|
65 | |
---|
66 | // ----------------------- |
---|
67 | // class XML_Node |
---|
68 | |
---|
69 | class XML_Node : virtual Noncopyable { |
---|
70 | protected: |
---|
71 | XML_Node *father; |
---|
72 | bool opened; |
---|
73 | int indent; |
---|
74 | |
---|
75 | public: |
---|
76 | XML_Node(bool is_tag); |
---|
77 | virtual ~XML_Node(); |
---|
78 | |
---|
79 | int Indent() const { return indent; } |
---|
80 | bool Opened() const { return opened; } |
---|
81 | |
---|
82 | virtual void add_son(XML_Node *son_, bool son_is_tag) = 0; |
---|
83 | virtual void remove_son(XML_Node *son_) = 0; |
---|
84 | virtual void open(FILE *out) = 0; |
---|
85 | virtual void close(FILE *out) = 0; |
---|
86 | }; |
---|
87 | |
---|
88 | // ---------------------------------------- |
---|
89 | // class XML_Tag : public XML_Node |
---|
90 | |
---|
91 | //! xml element |
---|
92 | class XML_Tag FINAL_TYPE : public XML_Node { // derived from a Noncopyable |
---|
93 | private: |
---|
94 | std::string name; |
---|
95 | XML_Node *son; |
---|
96 | XML_Attribute *attribute; |
---|
97 | int state; // 0 = no son; 1 = only content; 2 = son-tag; |
---|
98 | bool onExtraLine; // default = true; if false -> does not print linefeed before tag |
---|
99 | |
---|
100 | public: |
---|
101 | /*! Create a new xml element |
---|
102 | @param name_ element name |
---|
103 | */ |
---|
104 | XML_Tag(const std::string &name_); |
---|
105 | ~XML_Tag() OVERRIDE; |
---|
106 | |
---|
107 | /*! add an attribute to the XML_Tag |
---|
108 | @param name_ attribute name |
---|
109 | @param content_ attribute value |
---|
110 | */ |
---|
111 | void add_attribute(const std::string& name_, const std::string& content_); |
---|
112 | void add_attribute(const std::string& name_, int value); |
---|
113 | void add_son(XML_Node *son_, bool son_is_tag) OVERRIDE; |
---|
114 | void remove_son(XML_Node *son_) OVERRIDE; |
---|
115 | void open(FILE *out) OVERRIDE; |
---|
116 | void close(FILE *out) OVERRIDE; |
---|
117 | |
---|
118 | void set_on_extra_line(bool oel) { onExtraLine = oel; } |
---|
119 | }; |
---|
120 | |
---|
121 | //! a xml text node |
---|
122 | class XML_Text : public XML_Node { |
---|
123 | private: |
---|
124 | std::string content; |
---|
125 | |
---|
126 | public: |
---|
127 | /*! Create text (content) in xml |
---|
128 | @param content_ the content |
---|
129 | */ |
---|
130 | XML_Text(const std::string& content_) : XML_Node(false), content(content_) {} |
---|
131 | ~XML_Text() OVERRIDE; |
---|
132 | |
---|
133 | void add_son(XML_Node *son_, bool son_is_tag) OVERRIDE __ATTR__NORETURN; |
---|
134 | void remove_son(XML_Node *son_) OVERRIDE __ATTR__NORETURN; |
---|
135 | void open(FILE *) OVERRIDE; |
---|
136 | void close(FILE *out) OVERRIDE; |
---|
137 | }; |
---|
138 | |
---|
139 | class XML_Comment : public XML_Node { |
---|
140 | std::string content; |
---|
141 | public: |
---|
142 | XML_Comment(const std::string& content_) : XML_Node(false), content(content_) {} |
---|
143 | ~XML_Comment() OVERRIDE; |
---|
144 | |
---|
145 | void add_son(XML_Node *son_, bool son_is_tag) OVERRIDE __ATTR__NORETURN; |
---|
146 | void remove_son(XML_Node *son_) OVERRIDE __ATTR__NORETURN; |
---|
147 | void open(FILE *) OVERRIDE; |
---|
148 | void close(FILE *out) OVERRIDE; |
---|
149 | }; |
---|
150 | |
---|
151 | //! an entire xml document |
---|
152 | class XML_Document FINAL_TYPE : virtual Noncopyable { |
---|
153 | private: |
---|
154 | std::string dtd; |
---|
155 | XML_Tag *root; |
---|
156 | XML_Node *latest_son; |
---|
157 | FILE *out; |
---|
158 | |
---|
159 | public: |
---|
160 | /*! Create and stream (at destruction) a xml document |
---|
161 | @param name_ name of the root node |
---|
162 | @param dtd_ filename of dtd |
---|
163 | @param out_ FILE where xml document will be written to |
---|
164 | */ |
---|
165 | XML_Document(const std::string& name_, const std::string& dtd_, FILE *out_); |
---|
166 | virtual ~XML_Document() ; |
---|
167 | |
---|
168 | //! true -> tags w/o content or attributes are skipped (default = false) |
---|
169 | bool skip_empty_tags; |
---|
170 | |
---|
171 | //! how many columns are used per indentation level (defaults to 1) |
---|
172 | size_t indentation_per_level; |
---|
173 | |
---|
174 | XML_Node* LatestSon() { return latest_son; } |
---|
175 | void set_LatestSon(XML_Node* latest_son_) { latest_son = latest_son_; } |
---|
176 | |
---|
177 | XML_Tag& getRoot() { return *root; } |
---|
178 | |
---|
179 | void add_attribute(const std::string& name_, const std::string& content_) { |
---|
180 | getRoot().add_attribute(name_, content_); |
---|
181 | } |
---|
182 | |
---|
183 | FILE *Out() { return out; } |
---|
184 | }; |
---|
185 | |
---|
186 | #else |
---|
187 | #error xml.hxx included twice |
---|
188 | #endif // XML_HXX |
---|