OSDN Git Service

3d6283d3f02ff1ac26b2a2c78cb633b3903d9129
[liveml/LiveML.git] / src / xmlparser.h
1 /**
2  * LiveML - LiveML is screen(graphic) controling library using XML.
3  *
4  * LGPL License
5  * Copyright (C) 2010 Nothan
6  * http://github.com/nothan/liveml/
7  * All rights reserved.
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Library General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2 of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Library General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Library General Public
20  *  License along with this library; if not, write to the Free
21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  * Nothan
24  * private@nothan.xrea.jp
25  *
26  * Tsuioku Denrai
27  * http://tsuioku-denrai.xrea.jp/
28  */
29
30 #ifndef __XMLPARSER_H__
31 #define __XMLPARSER_H__
32
33 #include <vector>
34 #include <string>
35 #include "list.hpp"
36 using namespace std;
37
38 #ifdef DEBUG
39 #define DCODE(code) code
40 #else
41 #define DCODE(code)
42 #endif
43
44 #define PARAMFUNC(name) void* name(const char* value, XMLParser &parser)
45 #define LML_TAGFUNC(name) XML_TAGRTN name(Parameter &param, XMLParser &parser)
46
47 typedef enum
48 {
49   XML_TAGRTN_NULL = 0,
50   XML_TAGRTN_LEVEL,
51   XML_TAGRTN_STOP,
52   XML_TAGRTN_SKIP
53 } XML_TAGRTN;
54
55 typedef size_t tag_type;
56 typedef size_t action_type;
57 typedef size_t param_type;
58
59 class Parameter;
60 class XMLParser;
61 struct Tag;
62
63 class ParameterOption {
64 protected:
65   struct ReplaceValue {
66     string value;
67     string to;
68   };
69   size_t _index;
70   string _name;
71   param_type _type;
72   vector<ReplaceValue> _replaces;
73
74 public:
75   ~ParameterOption()
76   {
77   }
78
79   void set(size_t index, param_type type, const char *name = NULL)
80   {
81     if (name != NULL) _name = name;
82     _index = index;
83     _type = type;
84   }
85
86   string& getName(void)
87   {
88     return _name;
89   }
90
91   size_t getIndex(void)
92   {
93     return _index;
94   }
95
96   param_type getType(void)
97   {
98     return _type;
99   }
100
101   void addReplaceValue(const char* value, const char *to)
102   {
103     ReplaceValue rep = {value, to};
104     _replaces.push_back(rep);
105   }
106   const char* getReplaceValue(const char* value)
107   {
108     for (size_t i = 0; i < _replaces.size(); i++)
109     {
110       if (_replaces[i].value == value) return _replaces[i].to.c_str();
111     }
112     return value;
113   }
114 };
115
116 class Parameter
117 {
118   vector<void*> values;
119 public:
120   Parameter(void)
121   {
122     for (size_t i = 0; i < values.size(); i++) free(values[i]);
123   }
124
125   void unset(size_t index)
126   {
127     if (values[index] == NULL) return;
128     free(values[index]);
129     values[index] = NULL;
130   }
131
132   bool has(size_t index)
133   {
134     if (values.size() < index + 1) return false;
135     return values[index] != NULL;
136   }
137
138   const void* get(size_t index)
139   {
140     if (values.size() < index + 1) return NULL;
141     return values[index];
142   }
143
144   void set(size_t index, void *data)
145   {
146     if (values.size() < index + 1) values.resize(index + 1);
147     else unset(index);
148     values[index] = data;
149   }
150
151   Tag* getTag(size_t index)
152   {
153     return (Tag*)get(index);
154   }
155
156   const char* getString(size_t index)
157   {
158     return (const char*)values[index];
159   }
160
161   size_t getENum(size_t index)
162   {
163     return *(size_t*)values[index];
164   }
165
166   bool cmpHash(size_t index, const char*buf)
167   {
168     for (size_t i = 0; i < 4; i++)
169     {
170       if (((int*)values[index])[i] != ((int*)buf)[i]) return false;
171     }
172
173     return true;
174   }
175 };
176
177 class UNameItem
178 {
179 protected:
180   string _name;
181 public:
182   void setName(string name)
183   {
184     _name = name;
185   }
186   string& getName()
187   {
188     return _name;
189   }
190 };
191
192 template <class T>
193 class NameContainer
194 {
195 protected:
196   vector<T> _list;
197 public:
198   static const size_t NOTFOUND = 0xFFFFFFFF;
199
200   virtual ~NameContainer()
201   {
202   }
203
204   T* operator[](size_t id)
205   {
206     return get(id);
207   }
208
209   T* operator[](const char* name)
210   {
211     return get(getId(name));
212   }
213
214   virtual T* add(void)
215   {
216     _list.resize(_list.size() + 1);
217     T &i = _list.back();
218
219     return &i;
220   }
221
222   T* get(size_t id)
223   {
224     if (id >= _list.size()) return NULL;
225
226     return &_list[id];
227   }
228
229   virtual size_t getId(const char *name)
230   {
231     for (tag_type i = 0; i < _list.size(); i++)
232     {
233       if (_list[i].getName() == name) return i;
234     }
235
236     return NOTFOUND;
237   }
238
239   bool has(const char *name)
240   {
241     return getId(name) != NOTFOUND;
242   }
243
244   bool has(size_t id)
245   {
246     return id != NOTFOUND;
247   }
248
249   size_t size(void)
250   {
251     return _list.size();
252   }
253
254   void resize(size_t size)
255   {
256     _list.resize(size);
257   }
258 };
259
260 template <class T>
261 class UNameContainer : public NameContainer<T>
262 {
263 public:
264   T* add(const char *name)
265   {
266     size_t id = NameContainer<T>::getId(name);
267
268     if (id != NameContainer<T>::NOTFOUND)
269     {
270       return NameContainer<T>::get(id);
271     }
272     T &i = *NameContainer<T>::add();
273     i.setName(name);
274
275     return &i;
276   }
277 };
278
279 class TagType : public UNameItem
280 {
281 protected:
282   XML_TAGRTN (*_func)(Parameter&, XMLParser&);
283   vector<ParameterOption> _params;
284
285 public:
286   tag_type id;
287   int level;
288   const char *parent;
289
290   TagType(void)
291   {
292     _func = NULL;
293   }
294
295   ParameterOption* addParameter(void)
296   {
297     _params.resize(_params.size() + 1);
298     return &_params.back();
299   }
300   ParameterOption* getParameter(size_t id)
301   {
302     if (id >= _params.size()) return NULL;
303
304     return &_params[id];
305   }
306   size_t countParameter(void)
307   {
308     return _params.size();
309   }
310
311   void setFunction(XML_TAGRTN (*f)(Parameter&, XMLParser&))
312   {
313     _func = f;
314   }
315   bool hasFunction(void)
316   {
317     return _func != NULL;
318   }
319   XML_TAGRTN (*getFunction(void))(Parameter&, XMLParser&)
320   {
321     return _func;
322   }
323 };
324
325 class TagTypeContainer : public UNameContainer<TagType>
326 {
327 public:
328   TagType* add(void)
329   {
330     TagType &i = *NameContainer<TagType>::add();
331     i.id = _list.size() - 1;
332
333     return &i;
334   }
335
336   TagType* add(const char *name,  const char *parent = NULL)
337   {
338     TagType &i = *UNameContainer<TagType>::add(name);
339     i.id = _list.size() - 1;
340     i.parent = parent;
341
342     return &i;
343   }
344 };
345
346 struct Tag
347 {
348   TagType *type;
349   Parameter param;
350 };
351
352 struct ParameterType
353 {
354   void* (*func)(const char*, XMLParser&);
355 };
356
357 class XMLParser : public TagTypeContainer
358 {
359 protected:
360   TagTypeContainer _tagTypeContainer;
361   vector<TagType> _registerTags;
362   vector<ParameterType> _parameterTypes;
363   Tag* _currentTag;
364   Tag* _parentTag;
365
366   static PARAMFUNC(paramString);
367   static PARAMFUNC(paramTag);
368   static PARAMFUNC(paramCloseTag);
369   static PARAMFUNC(paramParentTag);
370
371 public:
372   const param_type PARAM_STRING;
373   const param_type PARAM_TAG;
374   const param_type PARAM_CLOSE_TAG;
375   const param_type PARAM_PARENT_TAG;
376
377   list<Tag> tagList;
378   list<Tag*> tagLevelList;
379
380   XMLParser(void);
381   param_type registerParameterType(void*(*func)(const char*, XMLParser&));
382
383   virtual bool loadText(const char *text) = 0;
384   virtual bool loadFile(const char *file) = 0;
385
386   TagType* addTagType(const char *name,  const char *parent = NULL)
387   {
388     return _tagTypeContainer.add(name, parent);
389   }
390   TagType* getTagType(const char *name) { return _tagTypeContainer[name]; }
391   tag_type getTagTypeId(const char *name) { return _tagTypeContainer.getId(name); }
392   size_t countTagType(void) { return _tagTypeContainer.size(); };
393   bool checkTagLevel(TagType*);
394
395   Tag* addTag(TagType*);
396   void setCurrentTag(Tag *t) { _currentTag = t; }
397   Tag* getCurrentTag(void) { return _currentTag; }
398   void setParentTag(Tag *t) { _parentTag = t; }
399   Tag* getParentTag(void) { return _parentTag; }
400 };
401
402 #endif // __XMLPARSER_H__