From 02b9e16833acbdaa820bd3b8b64d652a41a8ff58 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 23 Jun 2009 18:54:46 +0200 Subject: XmlPacket-Klasse ?berarbeitet --- src/Common/XmlPacket.h | 574 +++++++++++++++++++++++-------------------------- 1 file changed, 272 insertions(+), 302 deletions(-) (limited to 'src/Common/XmlPacket.h') 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 +#include +#include +#include +#include +#include + +#include + 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 > 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 - void set(T val) { - switch(type) { - case INT: - value.var_int = static_cast(val); - break; - case UINT: - value.var_uint = static_cast(val); - break; - case INT64: - value.var_int64 = static_cast(val); - break; - case UINT64: - value.var_uint64 = static_cast(val); - break; - case FLOAT: - value.var_float = static_cast(val); - break; - case DOUBLE: - value.var_double = static_cast(val); - break; - case LONGDOUBLE: - value.var_ldouble = static_cast(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 + 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 - operator T() const { - switch(type) { - case INT: - return static_cast(value.var_int); - case UINT: - return static_cast(value.var_uint); - case INT64: - return static_cast(value.var_int64); - case UINT64: - return static_cast(value.var_uint64); - case FLOAT: - return static_cast(value.var_float); - case DOUBLE: - return static_cast(value.var_double); - case LONGDOUBLE: - return static_cast(value.var_ldouble); - default: - return static_cast(0); - } + void set(int val) { + set(val, INT); } - operator std::string() const { - return str; + void set(unsigned int val) { + set(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 &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 elements; std::map lists; - static Element nilElement; + Element* getElement(const std::string &name) { + std::map::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::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::iterator element = elements.begin(); element != elements.end(); ++element) + delete element->second; - return add(name, buf.str(), "int"); + for(std::map::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 + 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 + T get(const std::string &name) const { + Element *element = getElement(name); + if(!element) + return T(); + + switch(element->type) { + case Element::INT: + return static_cast(boost::get(element->value)); + case Element::UINT: + return static_cast(boost::get(element->value)); + case Element::INT64: + return static_cast(boost::get(element->value)); + case Element::UINT64: + return static_cast(boost::get(element->value)); + case Element::FLOAT: + return static_cast(boost::get(element->value)); + case Element::DOUBLE: + return static_cast(boost::get(element->value)); + case Element::LONGDOUBLE: + return static_cast(boost::get(element->value)); + default: + return static_cast(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::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::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::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::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::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 entries; - public: + template + 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::iterator entry = entries.begin(); entry != entries.end(); ++entry) + delete *entry; + } - virtual size_t getSize() const { + public: + typedef iterator_base::iterator> iterator; + typedef iterator_base::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 + 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 + T get(const std::string &name) const { + return entry->get(name); } - template - 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(const std::string &name) const; +template <> const std::string& XmlPacket::Entry::get(const std::string &name) const; + +template <> std::vector XmlPacket::Entry::get >(const std::string &name) const; +template <> const std::vector& XmlPacket::Entry::get&>(const std::string &name) const; + } } -- cgit v1.2.3