Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ParamNode.h
Go to the documentation of this file.
1 /* Copyright (C) 2010 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_PARAMNODE
19 #define INCLUDED_PARAMNODE
20 
21 #include "lib/file/vfs/vfs_path.h"
22 #include "maths/Fixed.h"
23 #include "ps/CStrIntern.h"
24 #include "ps/Errors.h"
26 
27 #include <map>
28 #include <set>
29 
30 class XMBFile;
31 class XMBElement;
32 
33 /**
34  * An entity initialisation parameter node.
35  * Each node has a text value, plus a number of named child nodes (in a tree structure).
36  * Child nodes are unordered, and there cannot be more than one with the same name.
37  * Nodes are immutable.
38  *
39  * Nodes can be initialised from XML files. Child elements are mapped onto child nodes.
40  * Attributes are mapped onto child nodes with names prefixed by "@"
41  * (e.g. the XML <code>&lt;a b="c">&lt;d/>&lt;/a></code> is loaded as a node with two
42  * child nodes, one called "@b" and one called "d").
43  *
44  * They can also be initialised from @em multiple XML files,
45  * which is used by ICmpTemplateManager for entity template inheritance.
46  * Loading one XML file like:
47  * @code
48  * <Entity>
49  * <Example1>
50  * <A attr="value">text</A>
51  * </Example1>
52  * <Example2>
53  * <B/>
54  * </Example2>
55  * <Example3>
56  * <C/>
57  * </Example3>
58  * <Example4 datatype="tokens">
59  * one two three
60  * </Example4>
61  * </Entity>
62  * @endcode
63  * then a second like:
64  * @code
65  * <Entity>
66  * <Example1>
67  * <A>example</A> <!-- replace the content of the old A element -->
68  * <D>new</D> <!-- add a new child to the old Example1 element -->
69  * </Example1>
70  * <Example2 disable=""/> <!-- delete the old Example2 element -->
71  * <Example3 replace=""> <!-- replace all the old children of the Example3 element -->
72  * <D>new</D>
73  * </Example3>
74  * <Example4 datatype="tokens"> <!-- treat as space-separated lists of tokens to merge -->
75  * four <!-- add a token to the parent's set -->
76  * -two <!-- remove a token from the parent's set -->
77  * </Example4>
78  * </Entity>
79  * @endcode
80  * is equivalent to loading a single file like:
81  * @code
82  * <Entity>
83  * <Example1>
84  * <A attr="value">example</A>
85  * <D>new</D>
86  * </Example1>
87  * <Example3>
88  * <D>new</D>
89  * </Example3>
90  * <Example4>
91  * one three four
92  * </Example4>
93  * </Entity>
94  * @endcode
95  *
96  * Parameter nodes can be translated to JavaScript objects. The previous example will become the object:
97  * @code
98  * { "Entity": {
99  * "Example1": {
100  * "A": { "@attr": "value", "_string": "example" },
101  * "D": "new"
102  * },
103  * "Example3": {
104  * "D": "new"
105  * },
106  * "Example4": { "@datatype": "tokens", "_string": "one three four" }
107  * }
108  * }
109  * @endcode
110  * (Note the special @c _string for the hopefully-rare cases where a node contains both child nodes and text.)
111  */
113 {
114 public:
115  typedef std::map<std::string, CParamNode> ChildrenMap;
116 
117  /**
118  * Constructs a new, empty node.
119  */
120  CParamNode(bool isOk = true);
121 
122  /**
123  * Loads the XML data specified by @a file into the node @a ret.
124  * Any existing data in @a ret will be overwritten or else kept, so this
125  * can be called multiple times to build up a node from multiple inputs.
126  *
127  * @param sourceIdentifier Optional; string you can pass along to indicate the source of
128  * the data getting loaded. Used for output to log messages if an error occurs.
129  */
130  static void LoadXML(CParamNode& ret, const XMBFile& file, const wchar_t* sourceIdentifier = NULL);
131 
132  /**
133  * Loads the XML data specified by @a path into the node @a ret.
134  * Any existing data in @a ret will be overwritten or else kept, so this
135  * can be called multiple times to build up a node from multiple inputs.
136  */
137  static void LoadXML(CParamNode& ret, const VfsPath& path);
138 
139  /**
140  * See LoadXML, but parses the XML string @a xml.
141  * @return error code if parsing failed, else @c PSRETURN_OK
142  *
143  * @param sourceIdentifier Optional; string you can pass along to indicate the source of
144  * the data getting loaded. Used for output to log messages if an error occurs.
145  */
146  static PSRETURN LoadXMLString(CParamNode& ret, const char* xml, const wchar_t* sourceIdentifier = NULL);
147 
148  /**
149  * Finds the childs named @a name from @a src and from @a this, and copies the source child's children
150  * which are in the @a permitted set into this node's child.
151  * Intended for use as a filtered clone of XML files.
152  * @a this and @a src must have childs named @a name.
153  */
154  void CopyFilteredChildrenOfChild(const CParamNode& src, const char* name, const std::set<std::string>& permitted);
155 
156  /**
157  * Returns the (unique) child node with the given name, or a node with IsOk() == false if there is none.
158  */
159  const CParamNode& GetChild(const char* name) const;
160  // (Children are returned as const in order to allow future optimisations, where we assume
161  // a node is always modified explicitly and not indirectly via its children, e.g. to cache jsvals)
162 
163  /**
164  * Returns true if this is a valid CParamNode, false if it represents a non-existent node
165  */
166  bool IsOk() const;
167 
168  /**
169  * Returns the content of this node as a string
170  */
171  const std::wstring& ToString() const;
172 
173  /**
174  * Returns the content of this node as an 8-bit string
175  */
176  const std::string ToUTF8() const;
177 
178  /**
179  * Returns the content of this node as an internalized 8-bit string. Should only be used for
180  * predictably small and frequently-used strings.
181  */
182  const CStrIntern ToUTF8Intern() const;
183 
184  /**
185  * Parses the content of this node as an integer
186  */
187  int ToInt() const;
188 
189  /**
190  * Parses the content of this node as a fixed-point number
191  */
192  fixed ToFixed() const;
193 
194  /**
195  * Parses the content of this node as a floating-point number
196  */
197  float ToFloat() const;
198 
199  /**
200  * Parses the content of this node as a boolean ("true" == true, anything else == false)
201  */
202  bool ToBool() const;
203 
204  /**
205  * Returns the content of this node and its children as an XML string
206  */
207  std::wstring ToXML() const;
208 
209  /**
210  * Write the content of this node and its children as an XML string, to the stream
211  */
212  void ToXML(std::wostream& strm) const;
213 
214  /**
215  * Returns a jsval representation of this node and its children.
216  * If @p cacheValue is true, then the same jsval will be returned each time
217  * this is called (regardless of whether you passed the same @p cx - be careful
218  * to only use the cache in one context).
219  * When caching, the lifetime of @p cx must be longer than the lifetime of this node.
220  * The cache will be reset if *this* node is modified (e.g. by LoadXML),
221  * but *not* if any child nodes are modified (so don't do that).
222  */
223  jsval ToJSVal(JSContext* cx, bool cacheValue) const;
224 
225  /**
226  * Returns the names/nodes of the children of this node, ordered by name
227  */
228  const ChildrenMap& GetChildren() const;
229 
230  /**
231  * Escapes a string so that it is well-formed XML content/attribute text.
232  * (Replaces "&" with "&amp;" etc, and replaces invalid characters with U+FFFD.)
233  */
234  static std::wstring EscapeXMLString(const std::wstring& str);
235 
236 private:
237 
238  /**
239  * Overlays the specified data onto this node. See class documentation for the concept and examples.
240  *
241  * @param xmb Representation of the XMB file containing an element with the data to apply.
242  * @param element Element inside the specified @p xmb file containing the data to apply.
243  * @param sourceIdentifier Optional; string you can pass along to indicate the source of
244  * the data getting applied. Used for output to log messages if an error occurs.
245  */
246  void ApplyLayer(const XMBFile& xmb, const XMBElement& element, const wchar_t* sourceIdentifier = NULL);
247 
248  void ResetScriptVal();
249 
250  jsval ConstructJSVal(JSContext* cx) const;
251 
252  std::wstring m_Value;
254  bool m_IsOk;
255 
256  /**
257  * Caches the ToJSVal script representation of this node.
258  */
260 };
261 
262 #endif // INCLUDED_PARAMNODE
An entity initialisation parameter node.
Definition: ParamNode.h:112
CParamNode(bool isOk=true)
Constructs a new, empty node.
Definition: ParamNode.cpp:42
A simple fixed-point number class.
Definition: Fixed.h:115
jsval ConstructJSVal(JSContext *cx) const
Definition: ParamNode.cpp:329
bool ToBool() const
Parses the content of this node as a boolean (&quot;true&quot; == true, anything else == false) ...
Definition: ParamNode.cpp:236
void ApplyLayer(const XMBFile &xmb, const XMBElement &element, const wchar_t *sourceIdentifier=NULL)
Overlays the specified data onto this node.
Definition: ParamNode.cpp:74
static std::wstring EscapeXMLString(const std::wstring &str)
Escapes a string so that it is well-formed XML content/attribute text.
Definition: ParamNode.cpp:249
const std::wstring & ToString() const
Returns the content of this node as a string.
Definition: ParamNode.cpp:198
const std::string ToUTF8() const
Returns the content of this node as an 8-bit string.
Definition: ParamNode.cpp:203
bool IsOk() const
Returns true if this is a valid CParamNode, false if it represents a non-existent node...
Definition: ParamNode.cpp:193
int ToInt() const
Parses the content of this node as an integer.
Definition: ParamNode.cpp:213
tuple xml
Definition: tests.py:119
const ChildrenMap & GetChildren() const
Returns the names/nodes of the children of this node, ordered by name.
Definition: ParamNode.cpp:244
bool m_IsOk
Definition: ParamNode.h:254
void ResetScriptVal()
Definition: ParamNode.cpp:374
fixed ToFixed() const
Parses the content of this node as a fixed-point number.
Definition: ParamNode.cpp:222
static void LoadXML(CParamNode &ret, const XMBFile &file, const wchar_t *sourceIdentifier=NULL)
Loads the XML data specified by file into the node ret.
Definition: ParamNode.cpp:47
ChildrenMap m_Childs
Definition: ParamNode.h:253
const CParamNode & GetChild(const char *name) const
Returns the (unique) child node with the given name, or a node with IsOk() == false if there is none...
Definition: ParamNode.cpp:185
Interned 8-bit strings.
Definition: CStrIntern.h:37
u32 PSRETURN
Definition: Errors.h:75
float ToFloat() const
Parses the content of this node as a floating-point number.
Definition: ParamNode.cpp:227
Definition: path.h:75
static PSRETURN LoadXMLString(CParamNode &ret, const char *xml, const wchar_t *sourceIdentifier=NULL)
See LoadXML, but parses the XML string xml.
Definition: ParamNode.cpp:62
std::wstring m_Value
Definition: ParamNode.h:252
void CopyFilteredChildrenOfChild(const CParamNode &src, const char *name, const std::set< std::string > &permitted)
Finds the childs named name from src and from this, and copies the source child&#39;s children which are ...
Definition: ParamNode.cpp:170
CScriptValRooted m_ScriptVal
Caches the ToJSVal script representation of this node.
Definition: ParamNode.h:259
const CStrIntern ToUTF8Intern() const
Returns the content of this node as an internalized 8-bit string.
Definition: ParamNode.cpp:208
std::wstring ToXML() const
Returns the content of this node and its children as an XML string.
Definition: ParamNode.cpp:275
std::map< std::string, CParamNode > ChildrenMap
Definition: ParamNode.h:115
jsval ToJSVal(JSContext *cx, bool cacheValue) const
Returns a jsval representation of this node and its children.
Definition: ParamNode.cpp:316