The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
simple_wml.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License 2
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #ifndef SIMPLE_WML_HPP_INCLUDED
16 #define SIMPLE_WML_HPP_INCLUDED
17 
18 #include <string.h>
19 
20 #include <cstddef>
21 #include <iosfwd>
22 #include <map>
23 #include <string>
24 #include <vector>
25 
26 #include "exceptions.hpp"
27 
28 namespace simple_wml {
29 
30 struct error : public game::error {
31  error(const char* msg);
32 };
33 
35 {
36 public:
37  string_span() : str_(nullptr), size_(0)
38  {}
39  string_span(const char* str, int size) : str_(str), size_(size)
40  {}
41  string_span(const char* str) : str_(str), size_(strlen(str))
42  {}
43  string_span(const char* begin, const char* end) : str_(begin), size_(end - begin)
44  {}
45 
46  typedef const char* const_iterator;
47  typedef const char* iterator;
48  typedef const char value_type;
49 
50  bool operator==(const char* o) const {
51  const char* i1 = str_;
52  const char* i2 = str_ + size_;
53  while(i1 != i2 && *o && *i1 == *o) {
54  ++i1;
55  ++o;
56  }
57 
58  return i1 == i2 && *o == 0;
59  }
60  bool operator!=(const char* o) const {
61  return !operator==(o);
62  }
63  bool operator==(const std::string& o) const {
64  return size_ == o.size() && memcmp(str_, o.data(), size_) == 0;
65  }
66  bool operator!=(const std::string& o) const {
67  return !operator==(o);
68  }
69  bool operator==(const string_span& o) const {
70  return size_ == o.size_ && memcmp(str_, o.str_, size_) == 0;
71  }
72  bool operator!=(const string_span& o) const {
73  return !operator==(o);
74  }
75  bool operator<(const string_span& o) const {
76  const int len = size_ < o.size_ ? size_ : o.size_;
77  for(int n = 0; n < len; ++n) {
78  if(str_[n] != o.str_[n]) {
79  if(str_[n] < o.str_[n]) {
80  return true;
81  } else {
82  return false;
83  }
84  }
85  }
86 
87  return size_ < o.size_;
88  }
89 
90  const char* begin() const { return str_; }
91  const char* end() const { return str_ + size_; }
92 
93  int size() const { return size_; }
94  bool empty() const { return size_ == 0; }
95  bool is_null() const { return str_ == nullptr; }
96 
97  bool to_bool(bool default_value=false) const;
98  int to_int() const;
99  std::string to_string() const;
100 
101  //returns a duplicate of the string span in a new[] allocated buffer
102  char* duplicate() const;
103 
104 private:
105  const char* str_;
106  unsigned int size_;
107 };
108 
109 std::ostream& operator<<(std::ostream& o, const string_span& s);
110 
111 class document;
112 
113 class node
114 {
115 public:
116  node(document& doc, node* parent);
117  node(document& doc, node* parent, const char** str, int depth=0);
118  ~node();
119 
120  typedef std::pair<string_span, string_span> attribute;
121  typedef std::vector<node*> child_list;
122 
123  const string_span& operator[](const char* key) const;
124  const string_span& attr(const char* key) const {
125  return (*this)[key];
126  }
127 
128  bool has_attr(const char* key) const;
129 
130  //sets an attribute in the WML node. The node will keep a direct reference
131  //to key and value which it will maintain for its lifetime. The caller
132  //MUST guarantee that the key and value buffers remain valid for the
133  //lifetime of the node.
134  node& set_attr(const char* key, const char* value);
135 
136  //functions which are identical to set_attr() except that the buffer
137  //referred to by 'value' will be duplicated and the new buffer managed by
138  //the node. The caller may destroy the value buffer as soon as the function
139  //returns. The key buffer must remain valid for the lifetime of the node.
140  node& set_attr_dup(const char* key, const char* value);
141  node& set_attr_dup(const char* key, const string_span& value);
142 
143  node& set_attr_int(const char* key, int value);
144 
145  node& add_child(const char* name);
146  node& add_child_at(const char* name, size_t index);
147  void remove_child(const char* name, size_t index);
148  void remove_child(const string_span& name, size_t index);
149 
150  node* child(const char* name);
151  const node* child(const char* name) const;
152 
153  const child_list& children(const char* name) const;
154 
155  const string_span& first_child() const;
156 
157  bool is_dirty() const { return output_cache_.is_null(); }
158 
160 
161  int output_size() const;
162  void output(char*& buf, CACHE_STATUS status=DO_NOT_MODIFY_CACHE);
163 
164  void copy_into(node& n) const;
165 
166  bool no_children() const { return children_.empty(); }
167  bool one_child() const { return children_.size() == 1 && children_.begin()->second.size() == 1; }
168 
169  void apply_diff(const node& diff);
170 
171  void set_doc(document* doc);
172 
173  int nchildren() const;
174  int nattributes_recursive() const;
175 
176 private:
177  node(const node&);
178  void operator=(const node&);
179 
180  int get_children(const string_span& name);
181  int get_children(const char* name);
182 
183  void set_dirty();
184  void shift_buffers(ptrdiff_t offset);
185 
187 
188  typedef std::vector<attribute> attribute_list;
189  attribute_list attr_;
190 
192 
193  typedef std::pair<string_span, child_list> child_pair;
194  typedef std::vector<child_pair> child_map;
195 
196  static child_map::const_iterator find_in_map(const child_map& m, const string_span& attr);
197  static child_map::iterator find_in_map(child_map& m, const string_span& attr);
198  child_map children_;
199 
200  //a node position indicates the index into the child map where the node
201  //is, and then the index into the child list within where the node is.
202  struct node_pos {
204  : child_map_index(static_cast<unsigned short>(child_map_index)),
205  child_list_index(static_cast<unsigned short>(child_list_index))
206  {}
207  unsigned short child_map_index;
208  unsigned short child_list_index;
209  };
210 
211  //a list of all the children in order.
212  std::vector<node_pos> ordered_children_;
213 
214  void insert_ordered_child(int child_map_index, int child_list_index);
215  void remove_ordered_child(int child_map_index, int child_list_index);
216  void insert_ordered_child_list(int child_map_index);
217  void remove_ordered_child_list(int child_map_index);
218 
219  void check_ordered_children() const;
220 
222 };
223 
225 
227 
229 
230 class document
231 {
232 public:
233  document();
234  explicit document(char* buf, INIT_BUFFER_CONTROL control=INIT_TAKE_OWNERSHIP);
235  document(const char* buf, INIT_STATE state);
236  explicit document(string_span compressed_buf);
237  ~document();
238  const char* dup_string(const char* str);
239  node& root() { if(!root_) { generate_root(); } return *root_; }
240  const node& root() const { if(!root_) { const_cast<document*>(this)->generate_root(); } return *root_; }
241 
242  const char* output();
243  string_span output_compressed(bool bzip2 = false);
244 
245  void compress();
246 
247  document* clone();
248 
249  const string_span& operator[](const char* key) const {
250  return root()[key];
251  }
252 
253  const string_span& attr(const char* key) const {
254  return root()[key];
255  }
256 
257  node* child(const char* name) {
258  return root().child(name);
259  }
260 
261  const node* child(const char* name) const {
262  return root().child(name);
263  }
264 
265  const node::child_list& children(const char* name) const {
266  return root().children(name);
267  }
268 
269  node& set_attr(const char* key, const char* value) {
270  return root().set_attr(key, value);
271  }
272 
273  node& set_attr_dup(const char* key, const char* value) {
274  return root().set_attr_dup(key, value);
275  }
276 
278  buffers_.push_back(buffer);
279  }
280 
281  void swap(document& o);
282  void clear();
283 
284  static std::string stats();
285 
286 private:
287  void generate_root();
288  document(const document&);
289  void operator=(const document&);
290 
292  const char* output_;
293  std::vector<char*> buffers_;
295 
296  //linked list of documents for accounting purposes
297  void attach_list();
298  void detach_list();
301 };
302 
303 }
304 
305 #endif
void remove_ordered_child(int child_map_index, int child_list_index)
Definition: simple_wml.cpp:526
node & add_child(const char *name)
Definition: simple_wml.cpp:465
const char * const_iterator
Definition: simple_wml.hpp:46
string_span compressed_buf_
Definition: simple_wml.hpp:291
std::vector< attribute > attribute_list
Definition: simple_wml.hpp:188
string_span output_compressed(bool bzip2=false)
node & set_attr(const char *key, const char *value)
Definition: simple_wml.hpp:269
std::ostream & operator<<(std::ostream &o, const string_span &s)
Definition: simple_wml.cpp:200
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glew.h:1222
void apply_diff(const node &diff)
Definition: simple_wml.cpp:827
std::string to_string() const
Definition: simple_wml.cpp:181
void shift_buffers(ptrdiff_t offset)
Definition: simple_wml.cpp:723
void output(char *&buf, CACHE_STATUS status=DO_NOT_MODIFY_CACHE)
Definition: simple_wml.cpp:743
node(document &doc, node *parent)
Definition: simple_wml.cpp:206
void insert_ordered_child(int child_map_index, int child_list_index)
Definition: simple_wml.cpp:504
string_span output_cache_
Definition: simple_wml.hpp:221
static child_map::const_iterator find_in_map(const child_map &m, const string_span &attr)
Definition: simple_wml.cpp:663
std::vector< char * > buffers_
Definition: simple_wml.hpp:293
std::pair< string_span, child_list > child_pair
Definition: simple_wml.hpp:193
unsigned short child_list_index
Definition: simple_wml.hpp:208
int nattributes_recursive() const
Definition: simple_wml.cpp:919
node & set_attr_int(const char *key, int value)
Definition: simple_wml.cpp:439
const char * dup_string(const char *str)
node & set_attr(const char *key, const char *value)
Definition: simple_wml.cpp:411
node & add_child_at(const char *name, size_t index)
Definition: simple_wml.cpp:446
int get_children(const string_span &name)
Definition: simple_wml.cpp:651
attribute_list attr_
Definition: simple_wml.hpp:189
char * duplicate() const
Definition: simple_wml.cpp:186
const string_span & first_child() const
Definition: simple_wml.cpp:687
bool operator!=(const std::string &o) const
Definition: simple_wml.hpp:66
node & set_attr_dup(const char *key, const char *value)
Definition: simple_wml.hpp:273
document * doc_
Definition: simple_wml.hpp:186
string_span(const char *str, int size)
Definition: simple_wml.hpp:39
int nchildren() const
Definition: simple_wml.cpp:906
std::vector< child_pair > child_map
Definition: simple_wml.hpp:194
void insert_ordered_child_list(int child_map_index)
Definition: simple_wml.cpp:545
GLintptr offset
Definition: glew.h:1650
node * child(const char *name)
Definition: simple_wml.hpp:257
const char * output()
const node * child(const char *name) const
Definition: simple_wml.hpp:261
node * child(const char *name)
Definition: simple_wml.cpp:607
node_pos(int child_map_index, int child_list_index)
Definition: simple_wml.hpp:203
GLuint GLuint end
Definition: glew.h:1221
string_span(const char *begin, const char *end)
Definition: simple_wml.hpp:43
bool one_child() const
Definition: simple_wml.hpp:167
void remove_child(const char *name, size_t index)
Definition: simple_wml.cpp:602
GLsizei const GLfloat * value
Definition: glew.h:1817
bool operator<(const string_span &o) const
Definition: simple_wml.hpp:75
GLenum GLsizei len
Definition: glew.h:5662
bool has_attr(const char *key) const
Definition: simple_wml.cpp:403
GLenum GLuint GLsizei const char * buf
Definition: glew.h:2498
void remove_ordered_child_list(int child_map_index)
Definition: simple_wml.cpp:555
const char * end() const
Definition: simple_wml.hpp:91
bool operator==(const char *o) const
Definition: simple_wml.hpp:50
void operator=(const document &)
bool operator==(const std::string &o) const
Definition: simple_wml.hpp:63
unsigned short child_map_index
Definition: simple_wml.hpp:207
child_map children_
Definition: simple_wml.hpp:198
void swap(document &o)
const node & root() const
Definition: simple_wml.hpp:240
GLuint buffer
Definition: glew.h:1648
bool is_dirty() const
Definition: simple_wml.hpp:157
const string_span & operator[](const char *key) const
Definition: simple_wml.cpp:390
const char * output_
Definition: simple_wml.hpp:292
static std::string stats()
node & set_attr_dup(const char *key, const char *value)
Definition: simple_wml.cpp:427
GLuint index
Definition: glew.h:1782
std::vector< node * > child_list
Definition: simple_wml.hpp:121
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
void copy_into(node &n) const
Definition: simple_wml.cpp:806
const child_list & children(const char *name) const
Definition: simple_wml.cpp:634
bool to_bool(bool default_value=false) const
Definition: simple_wml.cpp:157
const char * begin() const
Definition: simple_wml.hpp:90
GLuint const GLchar * name
Definition: glew.h:1782
const string_span & operator[](const char *key) const
Definition: simple_wml.hpp:249
bool operator!=(const string_span &o) const
Definition: simple_wml.hpp:72
void check_ordered_children() const
Definition: simple_wml.cpp:572
GLsizeiptr size
Definition: glew.h:1649
string_span(const char *str)
Definition: simple_wml.hpp:41
GLclampd n
Definition: glew.h:5903
std::pair< string_span, string_span > attribute
Definition: simple_wml.hpp:120
const GLdouble * m
Definition: glew.h:6968
bool operator!=(const char *o) const
Definition: simple_wml.hpp:60
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:27
bool operator==(const string_span &o) const
Definition: simple_wml.hpp:69
void set_doc(document *doc)
Definition: simple_wml.cpp:895
const node::child_list & children(const char *name) const
Definition: simple_wml.hpp:265
bool is_null() const
Definition: simple_wml.hpp:95
std::vector< node_pos > ordered_children_
Definition: simple_wml.hpp:212
const string_span & attr(const char *key) const
Definition: simple_wml.hpp:253
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
GLdouble s
Definition: glew.h:1358
int output_size() const
Definition: simple_wml.cpp:697
void operator=(const node &)
GLsizei const GLcharARB ** string
Definition: glew.h:4503
void take_ownership_of_buffer(char *buffer)
Definition: simple_wml.hpp:277
bool no_children() const
Definition: simple_wml.hpp:166
const string_span & attr(const char *key) const
Definition: simple_wml.hpp:124
std::string node_to_string(const node &n)
Definition: simple_wml.cpp:794