summaryrefslogtreecommitdiffstats
path: root/src/Common/XmlPacket.h
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-06-23 18:54:46 +0200
committerMatthias Schiffer <matthias@gamezock.de>2009-06-23 18:54:46 +0200
commit02b9e16833acbdaa820bd3b8b64d652a41a8ff58 (patch)
tree092b9dd423c6c52812f3978770b87417abe69b9b /src/Common/XmlPacket.h
parent37c8bed9a5f2ae9141c461202fec5baa6fa21389 (diff)
downloadmad-02b9e16833acbdaa820bd3b8b64d652a41a8ff58.tar
mad-02b9e16833acbdaa820bd3b8b64d652a41a8ff58.zip
XmlPacket-Klasse ?berarbeitet
Diffstat (limited to 'src/Common/XmlPacket.h')
-rw-r--r--src/Common/XmlPacket.h574
1 files changed, 272 insertions, 302 deletions
diff --git a/src/Common/XmlPacket.h b/src/Common/XmlPacket.h
index 43ee2b2..b37b783 100644
--- a/src/Common/XmlPacket.h
+++ b/src/Common/XmlPacket.h
@@ -29,6 +29,14 @@
#include <libxml/parser.h>
+#include <boost/cstdint.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/variant/get.hpp>
+#include <boost/variant/variant.hpp>
+#include <boost/smart_ptr.hpp>
+
+#include <iostream>
+
namespace Mad {
namespace Common {
@@ -42,359 +50,221 @@ class XmlPacket {
xmlNodePtr packetNode;
Entry *entry;
- public:
- class Element {
- public:
+ class Element : private boost::noncopyable {
+ private:
+ friend class Entry;
+
enum Type {
- NONE, LIST, BINARY,
+ NONE, BINARY,
INT, UINT, INT64, UINT64,
FLOAT, DOUBLE, LONGDOUBLE, STRING
};
- protected:
- friend class Entry;
+ typedef boost::variant<long, unsigned long, long long, unsigned long long, float, double, long double, std::vector<boost::uint8_t> > Variant;
xmlNodePtr elementNode;
- private:
- // Prevent shallow copy
- Element(const Element &o);
- Element& operator=(const Element &o);
-
- std::string str;
- void *binData;
-
Type type;
- union Variant {
- int var_int;
- unsigned int var_uint;
-
- long long var_int64;
- unsigned long long var_uint64;
-
- float var_float;
- double var_double;
- long double var_ldouble;
-
- size_t var_size;
- } value;
-
- static Entry nilEntry;
-
- template<typename T>
- void set(T val) {
- switch(type) {
- case INT:
- value.var_int = static_cast<int>(val);
- break;
- case UINT:
- value.var_uint = static_cast<unsigned int>(val);
- break;
- case INT64:
- value.var_int64 = static_cast<long long>(val);
- break;
- case UINT64:
- value.var_uint64 = static_cast<unsigned long long>(val);
- break;
- case FLOAT:
- value.var_float = static_cast<float>(val);
- break;
- case DOUBLE:
- value.var_double = static_cast<double>(val);
- break;
- case LONGDOUBLE:
- value.var_ldouble = static_cast<long double>(val);
- break;
- default:
- break;
- }
+ Variant value;
- updateStr();
- }
+ std::string str;
void updateStr();
- protected:
- Element(xmlNodePtr node, Type type0) : elementNode(node), binData(0), type(type0) {}
-
- public:
Element(xmlNodePtr node);
- virtual ~Element();
-
- Type getType() const {
- return type;
- }
-
- virtual size_t getSize() const {
- return 0;
- }
-
- virtual bool isEmpty() const {
- switch(type) {
- case NONE:
- return true;
- case BINARY:
- return (value.var_size != 0);
- case STRING:
- return str.empty();
- default:
- return false;
- }
- }
-
- virtual Entry& operator[](size_t) {
- return nilEntry;
- }
-
- virtual const Entry& operator[](size_t) const {
- return nilEntry;
- }
-
- Entry& back() {
- if(isEmpty())
- return nilEntry;
-
- return operator[](getSize()-1);
- }
-
- const Entry& back() const {
- if(isEmpty())
- return nilEntry;
+ template <typename T>
+ void set(T val, Type type0) {
+ type = type0;
+ value = val;
- return operator[](getSize()-1);
+ updateStr();
}
- virtual bool insertEntry(size_t) {return false;}
- virtual bool addEntry() {return false;}
- virtual bool removeEntry(size_t) {return false;}
-
- template<typename T>
- operator T() const {
- switch(type) {
- case INT:
- return static_cast<T>(value.var_int);
- case UINT:
- return static_cast<T>(value.var_uint);
- case INT64:
- return static_cast<T>(value.var_int64);
- case UINT64:
- return static_cast<T>(value.var_uint64);
- case FLOAT:
- return static_cast<T>(value.var_float);
- case DOUBLE:
- return static_cast<T>(value.var_double);
- case LONGDOUBLE:
- return static_cast<T>(value.var_ldouble);
- default:
- return static_cast<T>(0);
- }
+ void set(int val) {
+ set<long>(val, INT);
}
- operator std::string() const {
- return str;
+ void set(unsigned int val) {
+ set<unsigned long>(val, UINT);
}
- const Element& operator=(int val) {
- set(val);
- return *this;
+ void set(long val) {
+ set(val, INT);
}
- const Element& operator=(unsigned int val) {
- set(val);
- return *this;
+ void set(unsigned long val) {
+ set(val, UINT);
}
- const Element& operator=(long long val) {
- set(val);
- return *this;
+ void set(long long val) {
+ set(val, INT64);
}
- const Element& operator=(unsigned long long val) {
- set(val);
- return *this;
+ void set(unsigned long long val) {
+ set(val, UINT64);
}
- const Element& operator=(float val) {
- set(val);
- return *this;
+ void set(float val) {
+ set(val, FLOAT);
}
- const Element& operator=(double val) {
- set(val);
- return *this;
+ void set(double val) {
+ set(val, DOUBLE);
}
- const Element& operator=(long double val) {
- set(val);
- return *this;
+ void set(long double val) {
+ set(val, LONGDOUBLE);
}
- const Element& operator=(const std::string &val) {
- if(type == STRING) {
- str = val;
- updateStr();
- }
-
- return *this;
+ void set(const std::string &val) {
+ type = STRING;
+ value = Element::Variant();
+ str = val;
+ updateStr();
}
- void setBinaryData(const void *data, size_t size);
-
- void getBinaryData(const void **data, size_t *size) const {
- if(type == BINARY) {
- *data = binData;
- *size = value.var_size;
- }
- else {
- *data = 0;
- *size = 0;
- }
+ void set(const std::vector<boost::uint8_t> &val) {
+ set(val, BINARY);
}
};
- class Entry {
+ public:
+ class Entry : private boost::noncopyable {
private:
friend class List;
-
- // Prevent shallow copy
- Entry(const Entry &o);
- Entry& operator=(const Entry &o);
+ friend class XmlPacket;
xmlNodePtr entryNode;
std::map<std::string, Element*> elements;
std::map<std::string, List*> lists;
- static Element nilElement;
+ Element* getElement(const std::string &name) {
+ std::map<std::string, Element*>::iterator element = elements.find(name);
- bool add(const std::string &name, const std::string &value, const char *type) {
- if(!entryNode)
- return false;
+ if(element != elements.end())
+ return element->second;
- if(lists.find(name) != lists.end() || elements.find(name) != elements.end())
- return false;
+ if(lists.find(name) != lists.end())
+ return 0;
- xmlNodePtr newNode = xmlNewTextChild(entryNode, 0, (xmlChar*)"value", (xmlChar*)value.c_str());
+ xmlNodePtr newNode = xmlNewTextChild(entryNode, 0, (xmlChar*)"value", (xmlChar*)"");
xmlSetProp(newNode, (xmlChar*)"name", (xmlChar*)name.c_str());
- xmlSetProp(newNode, (xmlChar*)"type", (xmlChar*)type);
+ xmlSetProp(newNode, (xmlChar*)"type", (xmlChar*)"");
- if(!elements.insert(std::make_pair(name, new Element(newNode))).second) {
- xmlUnlinkNode(newNode);
- xmlFreeNode(newNode);
+ Element* newElement = new Element(newNode);
- return false;
- }
+ elements.insert(std::make_pair(name, newElement));
- return true;
+ return newElement;
}
- public:
- Entry(xmlNodePtr node);
- virtual ~Entry();
+ Element* getElement(const std::string &name) const {
+ std::map<std::string, Element*>::const_iterator element = elements.find(name);
- Element& operator[](const std::string &name);
- const Element& operator[](const std::string &name) const;
-
- bool add(const std::string &name, int val) {
- std::ostringstream buf;
- buf << val;
-
- return add(name, buf.str(), "int");
+ if(element != elements.end())
+ return element->second;
+ else
+ return 0;
}
- bool add(const std::string &name, unsigned int val) {
- std::ostringstream buf;
- buf << val;
-
- return add(name, buf.str(), "uint");
- }
-
- bool add(const std::string &name, long val) {
- std::ostringstream buf;
- buf << val;
+ Entry(xmlNodePtr node);
+ ~Entry() {
+ for(std::map<std::string, Element*>::iterator element = elements.begin(); element != elements.end(); ++element)
+ delete element->second;
- return add(name, buf.str(), "int");
+ for(std::map<std::string, List*>::iterator list = lists.begin(); list != lists.end(); ++list)
+ delete list->second;
}
- bool add(const std::string &name, unsigned long val) {
- std::ostringstream buf;
- buf << val;
-
- return add(name, buf.str(), "uint");
- }
+ public:
+ template <typename T>
+ bool set(const std::string &name, T val) {
+ Element *element = getElement(name);
+ if(!element)
+ return false;
- bool add(const std::string &name, long long val) {
- std::ostringstream buf;
- buf << val;
+ element->set(val);
- return add(name, buf.str(), "int64");
+ return true;
}
- bool add(const std::string &name, unsigned long long val) {
- std::ostringstream buf;
- buf << val;
-
- return add(name, buf.str(), "uint64");
+ template <typename T>
+ T get(const std::string &name) const {
+ Element *element = getElement(name);
+ if(!element)
+ return T();
+
+ switch(element->type) {
+ case Element::INT:
+ return static_cast<T>(boost::get<long>(element->value));
+ case Element::UINT:
+ return static_cast<T>(boost::get<unsigned long>(element->value));
+ case Element::INT64:
+ return static_cast<T>(boost::get<long long>(element->value));
+ case Element::UINT64:
+ return static_cast<T>(boost::get<unsigned long long>(element->value));
+ case Element::FLOAT:
+ return static_cast<T>(boost::get<float>(element->value));
+ case Element::DOUBLE:
+ return static_cast<T>(boost::get<double>(element->value));
+ case Element::LONGDOUBLE:
+ return static_cast<T>(boost::get<long double>(element->value));
+ default:
+ return static_cast<T>(0);
+ }
}
- bool add(const std::string &name, float val) {
- std::ostringstream buf;
- buf << val;
+ List* createList(const std::string &name, bool unique = false) {
+ std::map<std::string, List*>::iterator list = lists.find(name);
- return add(name, buf.str(), "float");
- }
+ if(list != lists.end())
+ return unique ? 0 : list->second;
- bool add(const std::string &name, double val) {
- std::ostringstream buf;
- buf << val;
+ if(elements.find(name) != elements.end())
+ return 0;
- return add(name, buf.str(), "double");
- }
+ xmlNodePtr newNode = xmlNewChild(entryNode, 0, (xmlChar*)"list", 0);
+ xmlSetProp(newNode, (xmlChar*)"name", (xmlChar*)name.c_str());
- bool add(const std::string &name, long double val) {
- std::ostringstream buf;
- buf << val;
+ List *newList = new List(newNode);
- return add(name, buf.str(), "longdouble");
- }
+ lists.insert(std::make_pair(name, newList));
- bool add(const std::string &name, const std::string &val) {
- return add(name, val, "string");
+ return newList;
}
- bool addBinary(const std::string &name, const void *data, size_t size);
-
- bool addList(const std::string &name) {
- if(!entryNode)
- return false;
+ List* getList(const std::string &name) {
+ std::map<std::string, List*>::iterator list = lists.find(name);
- if(elements.find(name) != elements.end() || lists.find(name) != lists.end())
- return false;
+ if(list == lists.end())
+ return 0;
- xmlNodePtr newNode = xmlNewChild(entryNode, 0, (xmlChar*)"list", 0);
- xmlSetProp(newNode, (xmlChar*)"name", (xmlChar*)name.c_str());
+ return list->second;
+ }
- if(!lists.insert(std::make_pair(name, new List(newNode))).second) {
- xmlUnlinkNode(newNode);
- xmlFreeNode(newNode);
+ const List* getList(const std::string &name) const {
+ std::map<std::string, List*>::const_iterator list = lists.find(name);
- return false;
- }
+ if(list == lists.end())
+ return 0;
- return true;
+ return list->second;
}
- bool remove(const std::string &name) {
+ void unset(const std::string &name) {
std::map<std::string, Element*>::iterator element = elements.find(name);
if(element != elements.end()) {
xmlUnlinkNode(element->second->elementNode);
xmlFreeNode(element->second->elementNode);
+ delete element->second;
+
elements.erase(element);
- return true;
+ return;
}
std::map<std::string, List*>::iterator list = lists.find(name);
@@ -403,69 +273,162 @@ class XmlPacket {
xmlUnlinkNode(list->second->elementNode);
xmlFreeNode(list->second->elementNode);
+ delete list->second;
+
lists.erase(list);
- return true;
+ return;
}
- return false;
+ return;
}
};
- class List : public Element {
+ class List : private boost::noncopyable {
private:
- // Prevent shallow copy
- List(const List &o);
- List& operator=(const List &o);
+ friend class Entry;
+
+ xmlNodePtr elementNode;
std::vector<Entry*> entries;
- public:
+ template <typename Type, typename IteratorType>
+ class iterator_base {
+ public:
+ friend class List;
+
+ typedef Type value_type;
+
+ typedef value_type &reference;
+ typedef value_type *pointer;
+
+ typedef ssize_t difference_type;
+
+ private:
+ IteratorType it;
+
+ iterator_base(IteratorType it0) : it(it0) {}
+
+ public:
+ iterator_base() {}
+
+ reference operator*() const {
+ return **it;
+ }
+
+ iterator_base operator+(const difference_type &n) const {
+ return iterator(it+n);
+ }
+
+ iterator_base operator++(int) {
+ return iterator(it++);
+ }
+
+ iterator_base& operator++() {
+ ++it;
+ return *this;
+ }
+
+ iterator_base& operator+=(const difference_type &n) {
+ it += n;
+ return *this;
+ }
+
+ iterator_base operator-(const difference_type &n) const {
+ return iterator(it-n);
+ }
+
+ iterator_base operator--(int) {
+ return iterator(it--);
+ }
+
+ iterator_base& operator--() {
+ --it;
+ return *this;
+ }
+
+ iterator_base& operator-=(const difference_type &n) {
+ it -= n;
+ return *this;
+ }
+
+ bool operator==(const iterator_base &it2) {
+ return it2.it == it;
+ }
+
+ bool operator!=(const iterator_base &it2) {
+ return it2.it != it;
+ }
+
+ pointer operator->() const {
+ return *it;
+ }
+
+ reference operator[](const difference_type &n) const {
+ return *it[n];
+ }
+ };
+
List(xmlNodePtr node);
- virtual ~List();
+ ~List() {
+ for(std::vector<Entry*>::iterator entry = entries.begin(); entry != entries.end(); ++entry)
+ delete *entry;
+ }
- virtual size_t getSize() const {
+ public:
+ typedef iterator_base<Entry, std::vector<Entry*>::iterator> iterator;
+ typedef iterator_base<const Entry, std::vector<Entry*>::const_iterator> const_iterator;
+
+ size_t getSize() const {
return entries.size();
}
- virtual bool isEmpty() const {
+ bool isEmpty() const {
return entries.empty();
}
- virtual Entry& operator[](size_t i) {
+ Entry& operator[](size_t i) {
return *entries[i];
}
- virtual const Entry& operator[](size_t i) const {
+ const Entry& operator[](size_t i) const {
return *entries[i];
}
- virtual bool insertEntry(size_t i) {
- if(i > getSize())
- return false;
-
- xmlNodePtr newNode = xmlNewNode(0, (xmlChar*)"entry");
- xmlAddChild(elementNode, newNode);
+ iterator begin() {
+ return iterator(entries.begin());
+ }
- entries.insert(entries.begin()+i, new Entry(newNode));
+ const_iterator begin() const {
+ return const_iterator(entries.begin());
+ }
- return true;
+ iterator end() {
+ return iterator(entries.end());
}
- virtual bool addEntry() {
- return insertEntry(getSize());
+ const_iterator end() const {
+ return const_iterator(entries.end());
}
- virtual bool removeEntry(size_t i) {
- if(i >= getSize())
- return false;
+ // TODO Correct ordering
+ iterator insertEntry(iterator it) {
+ xmlNodePtr newNode = xmlNewNode(0, (xmlChar*)"entry");
+ xmlAddChild(elementNode, newNode);
- xmlUnlinkNode(entries[i]->entryNode);
- xmlFreeNode(entries[i]->entryNode);
+ return iterator(entries.insert(it.it, new Entry(newNode)));
+ }
- entries.erase(entries.begin()+i);
+ virtual iterator addEntry() {
+ return insertEntry(end());
+ }
- return true;
+ virtual void removeEntry(iterator it) {
+ xmlUnlinkNode(it->entryNode);
+ xmlFreeNode(it->entryNode);
+ delete *it.it;
+
+ entries.erase(it.it);
}
};
@@ -484,34 +447,41 @@ class XmlPacket {
std::string getType() const;
void setType(const std::string &type);
- Element& operator[](const std::string &name) {
- return entry->operator[](name);
+ template <typename T>
+ bool set(const std::string &name, T val) {
+ return entry->set(name, val);
}
- const Element& operator[](const std::string &name) const {
- return entry->operator[](name);
+ template <typename T>
+ T get(const std::string &name) const {
+ return entry->get<T>(name);
}
- template <typename T>
- bool add(const std::string &name, T val) {
- return entry->add(name, val);
+ List* createList(const std::string &name, bool unique = false) {
+ return entry->createList(name, unique);
}
- bool addBinary(const std::string &name, const void *data, size_t size) {
- return entry->addBinary(name, data, size);
+ List* getList(const std::string &name) {
+ return entry->getList(name);
}
- bool addList(const std::string &name) {
- return entry->addList(name);
+ const List* getList(const std::string &name) const {
+ return entry->getList(name);
}
- bool remove(const std::string &name) {
- return entry->remove(name);
+ void unset(const std::string &name) {
+ entry->unset(name);
}
Net::Packet encode(uint16_t requestId) const;
};
+template <> std::string XmlPacket::Entry::get<std::string>(const std::string &name) const;
+template <> const std::string& XmlPacket::Entry::get<const std::string&>(const std::string &name) const;
+
+template <> std::vector<boost::uint8_t> XmlPacket::Entry::get<std::vector<unsigned char> >(const std::string &name) const;
+template <> const std::vector<boost::uint8_t>& XmlPacket::Entry::get<const std::vector<unsigned char>&>(const std::string &name) const;
+
}
}