Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
XeroXMB.h
Go to the documentation of this file.
1 /* Copyright (C) 2011 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 /*
19  Xeromyces - XMB reading library
20 */
21 
22 /*
23 
24 Brief outline:
25 
26 XMB is a binary representation of XML, with some limitations
27 but much more efficiency (particularly for loading simple data
28 classes that don't need much initialisation).
29 
30 Main limitations:
31  * Only handles UTF16 internally. (It's meant to be a feature, but
32  can be detrimental if it's always being converted back to
33  ASCII.)
34  * Can't correctly handle mixed text/elements inside elements -
35  "<div> <b> Text </b> </div>" and "<div> Te<b/>xt </div>" are
36  considered identical.
37  * Tries to avoid using strings - you usually have to load the
38  numeric IDs and use them instead.
39  * Case-sensitive (but converts all element/attribute names in
40  the XML file to lowercase, so you only have to be careful in
41  the code)
42 
43 
44 Theoretical file structure:
45 
46 XMB_File {
47  char Header[4]; // because everyone has one; currently "XMB0"
48 
49  int ElementNameCount;
50  ZStrA ElementNames[];
51 
52  int AttributeNameCount;
53  ZStrA AttributeNames[];
54 
55  XMB_Node Root;
56 }
57 
58 XMB_Node {
59 0) int Length; // of entire struct, so it can be skipped over
60 
61 4) int ElementName;
62 
63 8) int AttributeCount;
64 12) int ChildCount;
65 
66 16) int ChildrenOffset; // == sizeof(Text)+sizeof(Attributes)
67 20) XMB_Text Text;
68  XMB_Attribute Attributes[];
69  XMB_Node Children[];
70 
71 }
72 
73 XMB_Attribute {
74  int Name;
75  ZStrW Value;
76 }
77 
78 ZStrA {
79  int Length; // in bytes
80  char* Text; // null-terminated ASCII
81 }
82 
83 ZStrW {
84  int Length; // in bytes
85  char16* Text; // null-terminated UTF16
86 }
87 
88 XMB_Text {
89 20) int Length; // 0 if there's no text, else 4+sizeof(Text) in bytes including terminator
90  // If Length != 0:
91 24) int LineNumber; // for e.g. debugging scripts
92 28) char16* Text; // null-terminated UTF16
93 }
94 
95 TODO: since the API was changed to return UTF-8 CStrs,
96 it'd make much more sense to store UTF-8 on disk too
97 (plus it'd save space).
98 
99 */
100 
101 #ifndef INCLUDED_XEROXMB
102 #define INCLUDED_XEROXMB
103 
104 // Define to use a std::map for name lookups rather than a linear search.
105 // (The map is usually slower.)
106 //#define XERO_USEMAP
107 
108 #include <string>
109 
110 #ifdef XERO_USEMAP
111 # include <map>
112 #endif
113 
114 #include "ps/CStr.h"
115 
116 // File headers, to make sure it doesn't try loading anything other than an XMB
117 extern const char* HeaderMagicStr;
118 extern const char* UnfinishedHeaderMagicStr;
119 
120 class XMBElement;
121 class XMBElementList;
122 class XMBAttributeList;
123 
124 
125 class XMBFile
126 {
127 public:
128 
129  XMBFile() : m_Pointer(NULL) {}
130 
131  // Initialise from the contents of an XMB file.
132  // FileData must remain allocated and unchanged while
133  // the XMBFile is being used.
134  // @return indication of success; main cause for failure is attempting to
135  // load a partially valid XMB file (e.g. if the game was interrupted
136  // while writing it), which we detect by checking the magic string.
137  bool Initialise(const char* FileData);
138 
139  // Returns the root element
140  XMBElement GetRoot() const;
141 
142 
143  // Returns internal ID for a given ASCII element/attribute string.
144  int GetElementID(const char* Name) const;
145  int GetAttributeID(const char* Name) const;
146 
147  // For lazy people (e.g. me) when speed isn't vital:
148 
149  // Returns element/attribute string for a given internal ID
150  std::string GetElementString(const int ID) const;
151  std::string GetAttributeString(const int ID) const;
152 
153 private:
154  const char* m_Pointer;
155 
156 #ifdef XERO_USEMAP
157  std::map<std::string, int> m_ElementNames;
158  std::map<std::string, int> m_AttributeNames;
159 #else
162  const char* m_ElementPointer;
163  const char* m_AttributePointer;
164 #endif
165 
166  std::string ReadZStrA();
167 };
168 
170 {
171 public:
173  : m_Pointer(0) {}
174 
175  XMBElement(const char* offset)
176  : m_Pointer(offset) {}
177 
178  int GetNodeName() const;
181  CStr8 GetText() const;
182  // Returns the line number of the text within this element,
183  // or -1 if there is no text
184  int GetLineNumber() const;
185 
186 private:
187  // Pointer to the start of the node
188  const char* m_Pointer;
189 };
190 
192 {
193 public:
195  : Count(0), m_Pointer(0), m_LastItemID(-2) {}
196 
197  XMBElementList(const char* offset, int count)
198  : Count(count),
199  m_Pointer(offset),
200  m_LastItemID(-2) {} // use -2 because it isn't x-1 where x is a non-negative integer
201 
202  // Get first element in list with the given name.
203  // Performance is linear in the number of elements in the list.
204  XMBElement GetFirstNamedItem(const int ElementName) const;
205 
206  XMBElement Item(const int id); // returns Children[id]
207 
208  int Count;
209 
210 private:
211  const char* m_Pointer;
212 
213  // For optimised sequential access:
215  const char* m_LastPointer;
216 };
217 
218 
220 {
222  XMBAttribute(int name, const CStr8& value)
223  : Name(name), Value(value) {};
224 
225  int Name;
226  CStr8 Value; // UTF-8 encoded
227 };
228 
230 {
231 public:
232  XMBAttributeList(const char* offset, int count)
233  : Count(count), m_Pointer(offset), m_LastItemID(-2) {};
234 
235  // Get the attribute value directly
236  CStr8 GetNamedItem(const int AttributeName) const;
237 
238  // Returns an attribute by position in the list
239  XMBAttribute Item(const int id);
240 
241  int Count;
242 
243 private:
244  // Pointer to start of attribute list
245  const char* m_Pointer;
246 
247  // For optimised sequential access:
249  const char* m_LastPointer;
250 };
251 
252 #endif // INCLUDED_XEROXMB
const char * m_Pointer
Definition: XeroXMB.h:188
XMBElementList(const char *offset, int count)
Definition: XeroXMB.h:197
const char * m_Pointer
Definition: XeroXMB.h:245
const char * UnfinishedHeaderMagicStr
Definition: XeroXMB.cpp:27
int m_AttributeNameCount
Definition: XeroXMB.h:161
const char * HeaderMagicStr
Definition: XeroXMB.cpp:26
XMBElement GetFirstNamedItem(const int ElementName) const
Definition: XeroXMB.cpp:214
int GetElementID(const char *Name) const
Definition: XeroXMB.cpp:104
XMBAttributeList GetAttributes() const
Definition: XeroXMB.cpp:185
XMBElementList GetChildNodes() const
Definition: XeroXMB.cpp:174
XMBAttributeList(const char *offset, int count)
Definition: XeroXMB.h:232
XMBElement(const char *offset)
Definition: XeroXMB.h:175
int GetLineNumber() const
Definition: XeroXMB.cpp:205
const char * m_LastPointer
Definition: XeroXMB.h:215
const char * m_LastPointer
Definition: XeroXMB.h:249
std::string ReadZStrA()
Definition: XeroXMB.cpp:75
bool Initialise(const char *FileData)
Definition: XeroXMB.cpp:31
const char * m_Pointer
Definition: XeroXMB.h:211
CStr8 GetText() const
Definition: XeroXMB.cpp:196
XMBAttribute Item(const int id)
Definition: XeroXMB.cpp:276
XMBFile()
Definition: XeroXMB.h:129
CStr8 GetNamedItem(const int AttributeName) const
Definition: XeroXMB.cpp:259
XMBElement()
Definition: XeroXMB.h:172
std::string GetElementString(const int ID) const
Definition: XeroXMB.cpp:148
const char * m_ElementPointer
Definition: XeroXMB.h:162
CStr8 Value
Definition: XeroXMB.h:226
XMBAttribute()
Definition: XeroXMB.h:221
XMBElement GetRoot() const
Definition: XeroXMB.cpp:84
const char * m_Pointer
Definition: XeroXMB.h:154
const char * m_AttributePointer
Definition: XeroXMB.h:163
int m_LastItemID
Definition: XeroXMB.h:214
int GetAttributeID(const char *Name) const
Definition: XeroXMB.cpp:124
std::string GetAttributeString(const int ID) const
Definition: XeroXMB.cpp:156
XMBAttribute(int name, const CStr8 &value)
Definition: XeroXMB.h:222
XMBElement Item(const int id)
Definition: XeroXMB.cpp:233
int m_ElementNameCount
Definition: XeroXMB.h:160
int GetNodeName() const
Definition: XeroXMB.cpp:166