Pyrogenesis  trunk
XMBData.h
Go to the documentation of this file.
1 /* Copyright (C) 2021 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 Brief outline:
22 
23 XMB originated as a binary representation of XML, with some limitations
24 but much more efficiency (particularly for loading simple data
25 classes that don't need much initialisation).
26 
27 Theoretical file structure:
28 
29 XMB_File {
30  char Header[4]; // because everyone has one; currently "XMB0"
31  u32 Version;
32 
33  int OffsetFromStartToElementNames;
34  int ElementNameCount;
35 
36  int OffsetFromStartToAttributeNames;
37  int AttributeNameCount;
38 
39  XMB_Node Root;
40 
41  ZStr8 ElementNames[];
42  ZStr8 AttributeNames[];
43 
44 }
45 
46 XMB_Node {
47 0) int Length; // of entire struct, so it can be skipped over
48 
49 4) int ElementName;
50 
51 8) int AttributeCount;
52 12) int ChildCount;
53 
54 16) int ChildrenOffset; // == sizeof(Text)+sizeof(Attributes)
55 20) XMB_Text Text;
56  XMB_Attribute Attributes[];
57  XMB_Node Children[];
58 
59 }
60 
61 XMB_Attribute {
62  int Name;
63  ZStr8 Value;
64 }
65 
66 ZStr8 {
67  int Length; // in bytes
68  char* Text; // null-terminated UTF8
69 }
70 
71 XMB_Text {
72 20) int Length; // 0 if there's no text, else 4+sizeof(Text) in bytes including terminator
73  // If Length != 0:
74 24) int LineNumber; // for e.g. debugging scripts
75 28) char* Text; // null-terminated UTF8
76 }
77 
78 */
79 
80 #ifndef INCLUDED_XEROXMB
81 #define INCLUDED_XEROXMB
82 
83 #include "ps/CStr.h"
84 
85 #include <string>
86 #include <string_view>
87 
88 class XMBStorage;
89 
90 class XMBElement;
91 class XMBElementList;
92 class XMBAttributeList;
93 
94 
95 class XMBData
96 {
97 public:
98 
99  XMBData() : m_Pointer(nullptr) {}
100 
101  /*
102  * Initialise from the contents of an XMBStorage.
103  * @param doc must remain allocated and unchanged while
104  * the XMBData is being used.
105  * @return indication of success; main cause for failure is attempting to
106  * load a partially valid XMB file (e.g. if the game was interrupted
107  * while writing it), which we detect by checking the magic string.
108  * It also fails when trying to load an XMB file with a different version.
109  */
110  bool Initialise(const XMBStorage& doc);
111 
112  // Returns the root element
113  XMBElement GetRoot() const;
114 
115  // Returns internal ID for a given element/attribute string.
116  int GetElementID(const char* Name) const;
117  int GetAttributeID(const char* Name) const;
118 
119  // Returns element/attribute string for a given internal ID.
120  const char* GetElementString(const int ID) const;
121  const char* GetAttributeString(const int ID) const;
122 
123  std::string_view GetElementStringView(const int ID) const;
124  std::string_view GetAttributeStringView(const int ID) const;
125 
126 private:
127  const char* m_Pointer;
128 
131  const char* m_ElementPointer;
132  const char* m_AttributePointer;
133 };
134 
136 {
137 public:
139  : m_Pointer(0) {}
140 
141  XMBElement(const char* offset)
142  : m_Pointer(offset) {}
143 
144  int GetNodeName() const;
145  XMBElementList GetChildNodes() const;
146  XMBAttributeList GetAttributes() const;
147  CStr8 GetText() const;
148  // Returns the line number of the text within this element,
149  // or -1 if there is no text
150  int GetLineNumber() const;
151 
152 private:
153  // Pointer to the start of the node
154  const char* m_Pointer;
155 };
156 
158 {
159 public:
160  XMBElementList(const char* offset, size_t count, const char* endoffset)
161  : m_Size(count), m_Pointer(offset), m_CurItemID(0), m_CurPointer(offset), m_EndPointer(endoffset) {}
162 
163  // Get first element in list with the given name.
164  // Performance is linear in the number of elements in the list.
165  XMBElement GetFirstNamedItem(const int ElementName) const;
166 
167  // Linear in the number of elements in the list
168  XMBElement operator[](size_t id); // returns Children[id]
169 
170  class iterator
171  {
172  public:
173  typedef ptrdiff_t difference_type;
175  typedef XMBElement reference; // Because we need to construct the object
176  typedef XMBElement pointer; // Because we need to construct the object
177  typedef std::forward_iterator_tag iterator_category;
178 
179  iterator(size_t size, const char* ptr, const char* endptr = NULL)
180  : m_Size(size), m_CurItemID(endptr ? size : 0), m_CurPointer(endptr ? endptr : ptr) {}
181  XMBElement operator*() const { return XMBElement(m_CurPointer); }
182  XMBElement operator->() const { return **this; }
183  iterator& operator++();
184 
185  bool operator==(const iterator& rhs) const
186  {
187  return m_Size == rhs.m_Size &&
188  m_CurItemID == rhs.m_CurItemID &&
189  m_CurPointer == rhs.m_CurPointer;
190  }
191  bool operator!=(const iterator& rhs) const { return !(*this == rhs); }
192  private:
193  size_t m_Size;
194  size_t m_CurItemID;
195  const char* m_CurPointer;
196  };
197  iterator begin() { return iterator(m_Size, m_Pointer); }
198  iterator end() { return iterator(m_Size, m_Pointer, m_EndPointer); }
199 
200  size_t size() const { return m_Size; }
201  bool empty() const { return m_Size == 0; }
202 
203 private:
204  size_t m_Size;
205 
206  const char* m_Pointer;
207 
208  // For optimised sequential access:
209  size_t m_CurItemID;
210  const char* m_CurPointer;
211 
212  const char* m_EndPointer;
213 };
214 
215 
217 {
219  XMBAttribute(int name, const CStr8& value)
220  : Name(name), Value(value) {};
221 
222  int Name;
223  CStr8 Value; // UTF-8 encoded
224 };
225 
227 {
228 public:
229  XMBAttributeList(const char* offset, size_t count, const char* endoffset)
230  : m_Size(count), m_Pointer(offset), m_CurItemID(0), m_CurPointer(offset), m_EndPointer(endoffset) {}
231 
232  // Get the attribute value directly
233  CStr8 GetNamedItem(const int AttributeName) const;
234 
235  // Linear in the number of elements in the list
236  XMBAttribute operator[](size_t id); // returns Children[id]
237 
238  class iterator
239  {
240  public:
241  typedef ptrdiff_t difference_type;
243  typedef XMBAttribute reference; // Because we need to construct the object
244  typedef XMBAttribute pointer; // Because we need to construct the object
245  typedef std::forward_iterator_tag iterator_category;
246 
247  iterator(size_t size, const char* ptr, const char* endptr = NULL)
248  : m_Size(size), m_CurItemID(endptr ? size : 0), m_CurPointer(endptr ? endptr : ptr) {}
249  XMBAttribute operator*() const;
250  XMBAttribute operator->() const { return **this; }
251  iterator& operator++();
252 
253  bool operator==(const iterator& rhs) const
254  {
255  return m_Size == rhs.m_Size &&
256  m_CurItemID == rhs.m_CurItemID &&
257  m_CurPointer == rhs.m_CurPointer;
258  }
259  bool operator!=(const iterator& rhs) const { return !(*this == rhs); }
260  private:
261  size_t m_Size;
262  size_t m_CurItemID;
263  const char* m_CurPointer;
264  };
265  iterator begin() const { return iterator(m_Size, m_Pointer); }
266  iterator end() const { return iterator(m_Size, m_Pointer, m_EndPointer); }
267 
268  size_t size() const { return m_Size; }
269  bool empty() const { return m_Size == 0; }
270 
271 private:
272  size_t m_Size;
273 
274  // Pointer to start of attribute list
275  const char* m_Pointer;
276 
277  // For optimised sequential access:
278  size_t m_CurItemID;
279  const char* m_CurPointer;
280 
281  const char* m_EndPointer;
282 };
283 
284 #endif // INCLUDED_XEROXMB
int GetAttributeID(const char *Name) const
Definition: XMBData.cpp:87
const char * m_EndPointer
Definition: XMBData.h:281
const char * m_Pointer
Definition: XMBData.h:154
int Name
Definition: XMBData.h:220
bool operator==(const iterator &rhs) const
Definition: XMBData.h:253
const char * m_CurPointer
Definition: XMBData.h:263
size_t m_Size
Definition: XMBData.h:193
Definition: XMBData.h:226
ptrdiff_t difference_type
Definition: XMBData.h:241
const char * m_Pointer
Definition: XMBData.h:275
size_t m_CurItemID
Definition: XMBData.h:262
bool operator==(const iterator &rhs) const
Definition: XMBData.h:185
size_t m_Size
Definition: XMBData.h:204
iterator begin()
Definition: XMBData.h:197
iterator end() const
Definition: XMBData.h:266
Definition: XMBData.h:157
Definition: XMBData.h:135
XMBAttributeList(const char *offset, size_t count, const char *endoffset)
Definition: XMBData.h:229
iterator(size_t size, const char *ptr, const char *endptr=NULL)
Definition: XMBData.h:179
size_t size() const
Definition: XMBData.h:200
size_t size() const
Definition: XMBData.h:268
XMBElement(const char *offset)
Definition: XMBData.h:141
XMBElement operator->() const
Definition: XMBData.h:182
iterator(size_t size, const char *ptr, const char *endptr=NULL)
Definition: XMBData.h:247
XMBAttribute pointer
Definition: XMBData.h:244
Storage for XMBData.
Definition: XMBStorage.h:37
int GetElementID(const char *Name) const
Definition: XMBData.cpp:67
Definition: XMBData.h:170
const char * m_Pointer
Definition: XMBData.h:206
Config::Value_type Value
Definition: json_spirit_value.h:182
XMBElement reference
Definition: XMBData.h:175
std::string_view GetAttributeStringView(const int ID) const
Definition: XMBData.cpp:122
size_t m_CurItemID
Definition: XMBData.h:194
bool empty() const
Definition: XMBData.h:201
XMBElement pointer
Definition: XMBData.h:176
Definition: XMBData.h:95
const char * m_CurPointer
Definition: XMBData.h:210
Definition: XMBData.h:216
std::forward_iterator_tag iterator_category
Definition: XMBData.h:177
const char * m_Pointer
Definition: XMBData.h:127
const char * GetAttributeString(const int ID) const
Definition: XMBData.cpp:112
bool operator!=(const iterator &rhs) const
Definition: XMBData.h:191
bool Initialise(const XMBStorage &doc)
Definition: XMBData.cpp:32
std::string_view GetElementStringView(const int ID) const
Definition: XMBData.cpp:117
int m_ElementNameCount
Definition: XMBData.h:129
const char * m_EndPointer
Definition: XMBData.h:212
const char * m_ElementPointer
Definition: XMBData.h:131
XMBData()
Definition: XMBData.h:99
XMBElement()
Definition: XMBData.h:138
CStr8 Value
Definition: XMBData.h:223
int m_AttributeNameCount
Definition: XMBData.h:130
const char * m_CurPointer
Definition: XMBData.h:195
bool operator!=(const iterator &rhs) const
Definition: XMBData.h:259
XMBAttribute()
Definition: XMBData.h:218
Definition: XMBData.h:238
XMBElement operator*() const
Definition: XMBData.h:181
XMBAttribute reference
Definition: XMBData.h:243
const char * GetElementString(const int ID) const
Definition: XMBData.cpp:107
XMBElement value_type
Definition: XMBData.h:174
size_t m_CurItemID
Definition: XMBData.h:209
const char * m_CurPointer
Definition: XMBData.h:279
bool empty() const
Definition: XMBData.h:269
size_t m_CurItemID
Definition: XMBData.h:278
XMBAttribute(int name, const CStr8 &value)
Definition: XMBData.h:219
const char * m_AttributePointer
Definition: XMBData.h:132
XMBAttribute operator->() const
Definition: XMBData.h:250
XMBAttribute value_type
Definition: XMBData.h:242
iterator end()
Definition: XMBData.h:198
std::forward_iterator_tag iterator_category
Definition: XMBData.h:245
size_t m_Size
Definition: XMBData.h:261
iterator begin() const
Definition: XMBData.h:265
XMBElement GetRoot() const
Definition: XMBData.cpp:62
XMBElementList(const char *offset, size_t count, const char *endoffset)
Definition: XMBData.h:160
size_t m_Size
Definition: XMBData.h:272
ptrdiff_t difference_type
Definition: XMBData.h:173