00001 #ifndef SIMPLE_WML_HPP_INCLUDED
00002 #define SIMPLE_WML_HPP_INCLUDED
00003
00004 #include <string.h>
00005
00006 #include <iosfwd>
00007 #include <map>
00008 #include <string>
00009 #include <vector>
00010
00011 namespace simple_wml {
00012
00013 struct error {
00014 error(const char* msg);
00015 };
00016
00017 class string_span
00018 {
00019 public:
00020 string_span() : str_(NULL), size_(0)
00021 {}
00022 string_span(const char* str, int size) : str_(str), size_(size)
00023 {}
00024 string_span(const char* str) : str_(str), size_(strlen(str))
00025 {}
00026
00027 bool operator==(const char* o) const {
00028 const char* i1 = str_;
00029 const char* i2 = str_ + size_;
00030 while(i1 != i2 && *o && *i1 == *o) {
00031 ++i1;
00032 ++o;
00033 }
00034
00035 return i1 == i2 && *o == 0;
00036 }
00037 bool operator!=(const char* o) const {
00038 return !operator==(o);
00039 }
00040 bool operator==(const std::string& o) const {
00041 return size_ == o.size() && memcmp(str_, o.data(), size_) == 0;
00042 }
00043 bool operator!=(const std::string& o) const {
00044 return !operator==(o);
00045 }
00046 bool operator==(const string_span& o) const {
00047 return size_ == o.size_ && memcmp(str_, o.str_, size_) == 0;
00048 }
00049 bool operator!=(const string_span& o) const {
00050 return !operator==(o);
00051 }
00052 bool operator<(const string_span& o) const {
00053 const int len = size_ < o.size_ ? size_ : o.size_;
00054 for(int n = 0; n < len; ++n) {
00055 if(str_[n] != o.str_[n]) {
00056 if(str_[n] < o.str_[n]) {
00057 return true;
00058 } else {
00059 return false;
00060 }
00061 }
00062 }
00063
00064 return size_ < o.size_;
00065 }
00066
00067 const char* begin() const { return str_; }
00068 const char* end() const { return str_ + size_; }
00069
00070 int size() const { return size_; }
00071 bool empty() const { return size_ == 0; }
00072 bool is_null() const { return str_ == NULL; }
00073
00074 bool to_bool(bool default_value=false) const;
00075 int to_int() const;
00076 std::string to_string() const;
00077
00078
00079 char* duplicate() const;
00080
00081 private:
00082 const char* str_;
00083 unsigned int size_;
00084 };
00085
00086 std::ostream& operator<<(std::ostream& o, const string_span& s);
00087
00088 class document;
00089
00090 class node
00091 {
00092 public:
00093 node(document& doc, node* parent);
00094 node(document& doc, node* parent, const char** str, int depth=0);
00095 ~node();
00096
00097 typedef std::pair<string_span, string_span> attribute;
00098 typedef std::vector<node*> child_list;
00099
00100 const string_span& operator[](const char* key) const;
00101 const string_span& attr(const char* key) const {
00102 return (*this)[key];
00103 }
00104
00105 bool has_attr(const char* key) const;
00106
00107 node& set_attr(const char* key, const char* value);
00108 node& set_attr_dup(const char* key, const char* value);
00109 node& set_attr_dup(const char* key, const string_span& value);
00110 node& set_attr_dup_key_and_value(const char* key, const char* value);
00111
00112 node& set_attr_int(const char* key, int value);
00113
00114 node& add_child(const char* name);
00115 node& add_child_at(const char* name, size_t index);
00116 void remove_child(const char* name, size_t index);
00117 void remove_child(const string_span& name, size_t index);
00118
00119 node* child(const char* name);
00120 const node* child(const char* name) const;
00121
00122 const child_list& children(const char* name) const;
00123
00124 const string_span& first_child() const;
00125
00126 bool is_dirty() const { return output_cache_.is_null(); }
00127
00128 int output_size() const;
00129 void output(char*& buf);
00130
00131 void copy_into(node& n) const;
00132
00133 bool no_children() const { return children_.empty(); }
00134 bool one_child() const { return children_.size() == 1 && children_.begin()->second.size() == 1; }
00135
00136 void apply_diff(const node& diff);
00137
00138 void set_doc(document* doc);
00139
00140 int nchildren() const;
00141 int nattributes_recursive() const;
00142
00143 private:
00144 node(const node&);
00145 void operator=(const node&);
00146
00147 child_list& get_children(const string_span& name);
00148 child_list& get_children(const char* name);
00149
00150 void set_dirty();
00151 void shift_buffers(ptrdiff_t offset);
00152
00153 document* doc_;
00154
00155 typedef std::vector<attribute> attribute_list;
00156 attribute_list attr_;
00157
00158 node* parent_;
00159
00160 typedef std::pair<string_span, child_list> child_pair;
00161 typedef std::vector<child_pair> child_map;
00162
00163 static child_map::const_iterator find_in_map(const child_map& m, const string_span& attr);
00164 static child_map::iterator find_in_map(child_map& m, const string_span& attr);
00165 child_map children_;
00166
00167 string_span output_cache_;
00168 };
00169
00170 enum INIT_BUFFER_CONTROL { INIT_TAKE_OWNERSHIP };
00171
00172 enum INIT_STATE { INIT_COMPRESSED, INIT_STATIC };
00173
00174 class document
00175 {
00176 public:
00177 document();
00178 explicit document(char* buf, INIT_BUFFER_CONTROL control=INIT_TAKE_OWNERSHIP);
00179 document(const char* buf, INIT_STATE state);
00180 explicit document(string_span compressed_buf);
00181 ~document();
00182 const char* dup_string(const char* str);
00183 node& root() { if(!root_) { generate_root(); } return *root_; }
00184 const node& root() const { if(!root_) { const_cast<document*>(this)->generate_root(); } return *root_; }
00185
00186 const char* output();
00187 string_span output_compressed();
00188
00189 void compress();
00190
00191 document* clone();
00192
00193 const string_span& operator[](const char* key) const {
00194 return root()[key];
00195 }
00196
00197 const string_span& attr(const char* key) const {
00198 return root()[key];
00199 }
00200
00201 node* child(const char* name) {
00202 return root().child(name);
00203 }
00204
00205 const node* child(const char* name) const {
00206 return root().child(name);
00207 }
00208
00209 node& set_attr(const char* key, const char* value) {
00210 return root().set_attr(key, value);
00211 }
00212
00213 node& set_attr_dup(const char* key, const char* value) {
00214 return root().set_attr_dup(key, value);
00215 }
00216
00217 void take_ownership_of_buffer(char* buffer) {
00218 buffers_.push_back(buffer);
00219 }
00220
00221 void swap(document& o);
00222 void clear();
00223
00224 static std::string stats();
00225
00226 private:
00227 void generate_root();
00228 document(const document&);
00229 void operator=(const document&);
00230
00231 string_span compressed_buf_;
00232 const char* output_;
00233 std::vector<char*> buffers_;
00234 node* root_;
00235
00236
00237 void attach_list();
00238 void detach_list();
00239 document* prev_;
00240 document* next_;
00241 };
00242
00243 }
00244
00245 #endif