summaryrefslogtreecommitdiffstats
path: root/src/Common
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
parent37c8bed9a5f2ae9141c461202fec5baa6fa21389 (diff)
downloadmad-02b9e16833acbdaa820bd3b8b64d652a41a8ff58.tar
mad-02b9e16833acbdaa820bd3b8b64d652a41a8ff58.zip
XmlPacket-Klasse ?berarbeitet
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/Request.cpp3
-rw-r--r--src/Common/RequestHandlers/DisconnectRequestHandler.cpp2
-rw-r--r--src/Common/RequestHandlers/FSInfoRequestHandler.cpp17
-rw-r--r--src/Common/RequestHandlers/SimpleRequestHandler.cpp10
-rw-r--r--src/Common/RequestHandlers/SimpleRequestHandlerGroup.cpp10
-rw-r--r--src/Common/RequestHandlers/StatusRequestHandler.cpp22
-rw-r--r--src/Common/RequestManager.cpp2
-rw-r--r--src/Common/Requests/DisconnectRequest.cpp3
-rw-r--r--src/Common/Requests/GroupUserListRequest.cpp2
-rw-r--r--src/Common/Requests/IdentifyRequest.cpp2
-rw-r--r--src/Common/Requests/UserGroupListRequest.cpp2
-rw-r--r--src/Common/Requests/UserInfoRequest.cpp2
-rw-r--r--src/Common/XmlPacket.cpp159
-rw-r--r--src/Common/XmlPacket.h574
14 files changed, 388 insertions, 422 deletions
diff --git a/src/Common/Request.cpp b/src/Common/Request.cpp
index 9aafd7f..9c2df5f 100644
--- a/src/Common/Request.cpp
+++ b/src/Common/Request.cpp
@@ -24,7 +24,8 @@ namespace Common {
void Request::handlePacket(boost::shared_ptr<const XmlPacket> packet) {
if(packet->getType() == "Error") {
- signalFinished(Core::Exception((*packet)["Where"], (*packet)["ErrorCode"], (*packet)["SubCode"], (*packet)["SubSubCode"]));
+ signalFinished(Core::Exception(packet->get<const std::string&>("Where"), packet->get<Core::Exception::ErrorCode>("ErrorCode"),
+ packet->get<long>("SubCode"), packet->get<long>("SubSubCode")));
return;
}
else if(packet->getType() != "OK") {
diff --git a/src/Common/RequestHandlers/DisconnectRequestHandler.cpp b/src/Common/RequestHandlers/DisconnectRequestHandler.cpp
index 11256b1..234591f 100644
--- a/src/Common/RequestHandlers/DisconnectRequestHandler.cpp
+++ b/src/Common/RequestHandlers/DisconnectRequestHandler.cpp
@@ -30,7 +30,7 @@ void DisconnectRequestHandler::handlePacket(boost::shared_ptr<const XmlPacket> p
XmlPacket ret;
ret.setType("Error");
- ret.add("ErrorCode", Core::Exception::UNEXPECTED_PACKET);
+ ret.set("ErrorCode", Core::Exception::UNEXPECTED_PACKET);
sendPacket(ret);
diff --git a/src/Common/RequestHandlers/FSInfoRequestHandler.cpp b/src/Common/RequestHandlers/FSInfoRequestHandler.cpp
index c036f7b..c381ab1 100644
--- a/src/Common/RequestHandlers/FSInfoRequestHandler.cpp
+++ b/src/Common/RequestHandlers/FSInfoRequestHandler.cpp
@@ -31,17 +31,16 @@ void FSInfoRequestHandler::handleRequest(boost::shared_ptr<const Common::XmlPack
getApplication()->getSystemManager()->getFSInfo(&fsInfo);
ret->setType("OK");
- ret->addList("filesystems");
+ XmlPacket::List *list = ret->createList("filesystems");
for(std::vector<SystemManager::FSInfo>::const_iterator fs = fsInfo.begin(); fs != fsInfo.end(); ++fs) {
- (*ret)["filesystems"].addEntry();
- XmlPacket::Entry &entry = (*ret)["filesystems"].back();
-
- entry.add("name", fs->fsName);
- entry.add("mountedOn", fs->mountedOn);
- entry.add("totalSize", fs->total);
- entry.add("usedSize", fs->used);
- entry.add("availableSize", fs->available);
+ XmlPacket::List::iterator entry = list->addEntry();
+
+ entry->set("name", fs->fsName);
+ entry->set("mountedOn", fs->mountedOn);
+ entry->set("totalSize", fs->total);
+ entry->set("usedSize", fs->used);
+ entry->set("availableSize", fs->available);
}
}
diff --git a/src/Common/RequestHandlers/SimpleRequestHandler.cpp b/src/Common/RequestHandlers/SimpleRequestHandler.cpp
index b6a22bf..bf72a80 100644
--- a/src/Common/RequestHandlers/SimpleRequestHandler.cpp
+++ b/src/Common/RequestHandlers/SimpleRequestHandler.cpp
@@ -31,7 +31,7 @@ void SimpleRequestHandler::handlePacket(boost::shared_ptr<const XmlPacket> packe
XmlPacket ret;
ret.setType("Error");
- ret.add("ErrorCode", Core::Exception::UNEXPECTED_PACKET);
+ ret.set("ErrorCode", Core::Exception::UNEXPECTED_PACKET);
sendPacket(ret);
@@ -48,10 +48,10 @@ void SimpleRequestHandler::handlePacket(boost::shared_ptr<const XmlPacket> packe
}
catch(Core::Exception e) {
ret.setType("Error");
- ret.add("ErrorCode", e.getErrorCode());
- ret.add("SubCode", e.getSubCode());
- ret.add("SubSubCode", e.getSubSubCode());
- ret.add("Where", e.getWhere());
+ ret.set("ErrorCode", e.getErrorCode());
+ ret.set("SubCode", e.getSubCode());
+ ret.set("SubSubCode", e.getSubSubCode());
+ ret.set("Where", e.getWhere());
}
sendPacket(ret);
diff --git a/src/Common/RequestHandlers/SimpleRequestHandlerGroup.cpp b/src/Common/RequestHandlers/SimpleRequestHandlerGroup.cpp
index 845021d..6546ce5 100644
--- a/src/Common/RequestHandlers/SimpleRequestHandlerGroup.cpp
+++ b/src/Common/RequestHandlers/SimpleRequestHandlerGroup.cpp
@@ -32,7 +32,7 @@ void SimpleRequestHandlerGroup::GroupRequestHandler::handlePacket(boost::shared_
XmlPacket ret;
ret.setType("Error");
- ret.add("ErrorCode", Core::Exception::UNEXPECTED_PACKET);
+ ret.set("ErrorCode", Core::Exception::UNEXPECTED_PACKET);
sendPacket(ret);
@@ -49,10 +49,10 @@ void SimpleRequestHandlerGroup::GroupRequestHandler::handlePacket(boost::shared_
}
catch(Core::Exception e) {
ret.setType("Error");
- ret.add("ErrorCode", e.getErrorCode());
- ret.add("SubCode", e.getSubCode());
- ret.add("SubSubCode", e.getSubSubCode());
- ret.add("Where", e.getWhere());
+ ret.set("ErrorCode", e.getErrorCode());
+ ret.set("SubCode", e.getSubCode());
+ ret.set("SubSubCode", e.getSubSubCode());
+ ret.set("Where", e.getWhere());
}
sendPacket(ret);
diff --git a/src/Common/RequestHandlers/StatusRequestHandler.cpp b/src/Common/RequestHandlers/StatusRequestHandler.cpp
index 50dbe11..d6cdc1e 100644
--- a/src/Common/RequestHandlers/StatusRequestHandler.cpp
+++ b/src/Common/RequestHandlers/StatusRequestHandler.cpp
@@ -34,8 +34,8 @@ void StatusRequestHandler::handleRequest(boost::shared_ptr<const Common::XmlPack
getApplication()->getSystemManager()->getUptimeInfo(&uptime, &idleTime);
- ret->add("uptime", uptime);
- ret->add("idleTime", idleTime);
+ ret->set("uptime", uptime);
+ ret->set("idleTime", idleTime);
}
catch(Core::Exception e) {}
@@ -44,10 +44,10 @@ void StatusRequestHandler::handleRequest(boost::shared_ptr<const Common::XmlPack
getApplication()->getSystemManager()->getMemoryInfo(&totalMem, &freeMem, &totalSwap, &freeSwap);
- ret->add("totalMem", totalMem);
- ret->add("freeMem", freeMem);
- ret->add("totalSwap", totalSwap);
- ret->add("freeSwap", freeSwap);
+ ret->set("totalMem", totalMem);
+ ret->set("freeMem", freeMem);
+ ret->set("totalSwap", totalSwap);
+ ret->set("freeSwap", freeSwap);
}
catch(Core::Exception e) {}
@@ -57,11 +57,11 @@ void StatusRequestHandler::handleRequest(boost::shared_ptr<const Common::XmlPack
getApplication()->getSystemManager()->getLoadInfo(&currentLoad, &nProcesses, &loadAvg1, &loadAvg5, &loadAvg15);
- ret->add("currentLoad", currentLoad);
- ret->add("nProcesses", nProcesses);
- ret->add("loadAvg1", loadAvg1);
- ret->add("loadAvg5", loadAvg5);
- ret->add("loadAvg15", loadAvg15);
+ ret->set("currentLoad", currentLoad);
+ ret->set("nProcesses", nProcesses);
+ ret->set("loadAvg1", loadAvg1);
+ ret->set("loadAvg5", loadAvg5);
+ ret->set("loadAvg15", loadAvg15);
}
catch(Core::Exception e) {}
}
diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp
index c8b27a2..ab45a8f 100644
--- a/src/Common/RequestManager.cpp
+++ b/src/Common/RequestManager.cpp
@@ -130,7 +130,7 @@ void RequestManager::receiveHandler(Connection *connection, boost::shared_ptr<co
XmlPacket ret;
ret.setType("Error");
- ret.add("ErrorCode", Core::Exception::UNEXPECTED_PACKET);
+ ret.set("ErrorCode", Core::Exception::UNEXPECTED_PACKET);
connection->sendPacket(ret, requestId);
}
diff --git a/src/Common/Requests/DisconnectRequest.cpp b/src/Common/Requests/DisconnectRequest.cpp
index 6c4fa0d..16a6a78 100644
--- a/src/Common/Requests/DisconnectRequest.cpp
+++ b/src/Common/Requests/DisconnectRequest.cpp
@@ -32,7 +32,8 @@ void DisconnectRequest::sendRequest() {
void DisconnectRequest::handlePacket(boost::shared_ptr<const XmlPacket> packet) {
if(packet->getType() == "Error") {
- signalFinished(Core::Exception((*packet)["Where"], (*packet)["ErrorCode"], (*packet)["SubCode"], (*packet)["SubSubCode"]));
+ signalFinished(Core::Exception(packet->get<const std::string&>("Where"), packet->get<Core::Exception::ErrorCode>("ErrorCode"),
+ packet->get<long>("SubCode"), packet->get<long>("SubSubCode")));
return;
}
else if(packet->getType() != "OK") {
diff --git a/src/Common/Requests/GroupUserListRequest.cpp b/src/Common/Requests/GroupUserListRequest.cpp
index f77f559..87ab1b5 100644
--- a/src/Common/Requests/GroupUserListRequest.cpp
+++ b/src/Common/Requests/GroupUserListRequest.cpp
@@ -26,7 +26,7 @@ namespace Requests {
void GroupUserListRequest::sendRequest() {
Common::XmlPacket packet;
packet.setType("ListGroupUsers");
- packet.add("gid", gid);
+ packet.set("gid", gid);
sendPacket(packet);
}
diff --git a/src/Common/Requests/IdentifyRequest.cpp b/src/Common/Requests/IdentifyRequest.cpp
index 6cf09d1..0be8e83 100644
--- a/src/Common/Requests/IdentifyRequest.cpp
+++ b/src/Common/Requests/IdentifyRequest.cpp
@@ -28,7 +28,7 @@ void IdentifyRequest::sendRequest() {
packet.setType("Identify");
if(!hostname.empty())
- packet.add("hostname", hostname);
+ packet.set("hostname", hostname);
sendPacket(packet);
}
diff --git a/src/Common/Requests/UserGroupListRequest.cpp b/src/Common/Requests/UserGroupListRequest.cpp
index ec7e23c..0c1a72f 100644
--- a/src/Common/Requests/UserGroupListRequest.cpp
+++ b/src/Common/Requests/UserGroupListRequest.cpp
@@ -26,7 +26,7 @@ namespace Requests {
void UserGroupListRequest::sendRequest() {
Common::XmlPacket packet;
packet.setType("ListUserGroups");
- packet.add("uid", uid);
+ packet.set("uid", uid);
sendPacket(packet);
}
diff --git a/src/Common/Requests/UserInfoRequest.cpp b/src/Common/Requests/UserInfoRequest.cpp
index 455eed6..b4b6940 100644
--- a/src/Common/Requests/UserInfoRequest.cpp
+++ b/src/Common/Requests/UserInfoRequest.cpp
@@ -26,7 +26,7 @@ namespace Requests {
void UserInfoRequest::sendRequest() {
Common::XmlPacket packet;
packet.setType("GetUserInfo");
- packet.add("uid", uid);
+ packet.set("uid", uid);
sendPacket(packet);
}
diff --git a/src/Common/XmlPacket.cpp b/src/Common/XmlPacket.cpp
index 6e3d007..8e612a9 100644
--- a/src/Common/XmlPacket.cpp
+++ b/src/Common/XmlPacket.cpp
@@ -24,58 +24,71 @@
#include <cstdlib>
#include <cstring>
+#include <iostream>
+
namespace Mad {
namespace Common {
-XmlPacket::Entry XmlPacket::Element::nilEntry(0);
-XmlPacket::Element XmlPacket::Entry::nilElement(0);
-
void XmlPacket::Element::updateStr() {
- if(type == NONE || type == LIST)
- return;
+ std::string typeStr;
- if(type == BINARY) {
- str = Base64Encoder::encode(std::vector<boost::uint8_t>((boost::uint8_t*)binData, ((boost::uint8_t*)binData)+value.var_size));
+ if(type == NONE) {
+ str = "";
+ }
+ else if(type == BINARY) {
+ str = Base64Encoder::encode(boost::get<std::vector<boost::uint8_t> >(value));
+ typeStr = "binary";
}
else if(type != STRING) {
std::ostringstream buf;
switch(type) {
case INT:
- buf << value.var_int;
+ buf << boost::get<long>(value);
+ typeStr = "int";
break;
case UINT:
- buf << value.var_uint;
+ buf << boost::get<unsigned long>(value);
+ typeStr = "uint";
break;
case INT64:
- buf << value.var_int64;
+ buf << boost::get<long long>(value);
+ typeStr = "int64";
break;
case UINT64:
- buf << value.var_uint64;
+ buf << boost::get<unsigned long long>(value);
+ typeStr = "uint64";
break;
case FLOAT:
- buf << value.var_float;
+ buf << boost::get<float>(value);
+ typeStr = "float";
break;
case DOUBLE:
- buf << value.var_double;
+ buf << boost::get<double>(value);
+ typeStr = "double";
break;
case LONGDOUBLE:
- buf << value.var_ldouble;
+ buf << boost::get<long double>(value);
+ typeStr = "longdouble";
default:
break;
}
str = buf.str();
}
+ else
+ typeStr = "string";
xmlNodePtr newNode = xmlNewText((xmlChar*)str.c_str());
xmlNodePtr oldNode = elementNode->children;
xmlReplaceNode(oldNode, newNode);
xmlFreeNode(oldNode);
+
+ xmlSetProp(elementNode, (xmlChar*)"type", (xmlChar*)typeStr.c_str());
}
-XmlPacket::Element::Element(xmlNodePtr node) : elementNode(node), binData(0), type(NONE) {
+XmlPacket::Element::Element(xmlNodePtr node) : elementNode(node), type(NONE) {
if(!node)
return;
@@ -94,39 +107,35 @@ XmlPacket::Element::Element(xmlNodePtr node) : elementNode(node), binData(0), ty
if(!xmlStrcmp(typestr, (xmlChar*)"binary")) {
type = BINARY;
- std::vector<boost::uint8_t> v = Base64Encoder::decode(str);
-
- value.var_size = v.size();
- binData = std::malloc(value.var_size);
- std::memcpy(binData, v.data(), value.var_size);
+ value = Base64Encoder::decode(str);
}
else if(!xmlStrcmp(typestr, (xmlChar*)"int")) {
type = INT;
- value.var_int = std::strtol((char*)content, 0, 10);
+ value = std::strtol((char*)content, 0, 10);
}
else if(!xmlStrcmp(typestr, (xmlChar*)"uint")) {
type = UINT;
- value.var_uint = std::strtoul((char*)content, 0, 10);
+ value = std::strtoul((char*)content, 0, 10);
}
else if(!xmlStrcmp(typestr, (xmlChar*)"int64")) {
type = INT64;
- value.var_int64 = std::strtoll((char*)content, 0, 10);
+ value = std::strtoll((char*)content, 0, 10);
}
else if(!xmlStrcmp(typestr, (xmlChar*)"uint64")) {
type = UINT64;
- value.var_uint64 = std::strtoull((char*)content, 0, 10);
+ value = std::strtoull((char*)content, 0, 10);
}
else if(!xmlStrcmp(typestr, (xmlChar*)"float")) {
type = FLOAT;
- value.var_float = std::strtof((char*)content, 0);
+ value = std::strtof((char*)content, 0);
}
else if(!xmlStrcmp(typestr, (xmlChar*)"double")) {
type = DOUBLE;
- value.var_double = std::strtod((char*)content, 0);
+ value = std::strtod((char*)content, 0);
}
else if(!xmlStrcmp(typestr, (xmlChar*)"longdouble")) {
type = LONGDOUBLE;
- value.var_ldouble = std::strtold((char*)content, 0);
+ value = std::strtold((char*)content, 0);
}
else if(!xmlStrcmp(typestr, (xmlChar*)"string")) {
type = STRING;
@@ -135,25 +144,8 @@ XmlPacket::Element::Element(xmlNodePtr node) : elementNode(node), binData(0), ty
xmlFree(typestr);
xmlFree(content);
- updateStr();
-}
-
-XmlPacket::Element::~Element() {
- if(binData)
- std::free(binData);
-}
-
-void XmlPacket::Element::setBinaryData(const void *data, size_t size) {
- if(type != BINARY)
- return;
-
- if(binData)
- std::free(binData);
-
- binData = std::malloc(size);
- std::memcpy(binData, data, size);
-
- updateStr();
+ if(type != NONE)
+ updateStr();
}
XmlPacket::Entry::Entry(xmlNodePtr node) : entryNode(node) {
@@ -175,51 +167,59 @@ XmlPacket::Entry::Entry(xmlNodePtr node) : entryNode(node) {
}
}
-XmlPacket::Entry::~Entry() {
- for(std::map<std::string, Element*>::iterator element = elements.begin(); element != elements.end(); ++element)
- delete element->second;
-
- for(std::map<std::string, List*>::iterator list = lists.begin(); list != lists.end(); ++list)
- delete list->second;
-}
-XmlPacket::Element& XmlPacket::Entry::operator[](const std::string &name) {
- std::map<std::string, Element*>::iterator it = elements.find(name);
- if(it != elements.end())
- return *it->second;
- std::map<std::string, List*>::iterator it2 = lists.find(name);
- if(it2 != lists.end())
- return *it2->second;
+template <>
+std::string XmlPacket::Entry::get<std::string>(const std::string &name) const {
+ Element *element = getElement(name);
+ if(!element)
+ return std::string();
- return nilElement;
+ return element->str;
}
-const XmlPacket::Element& XmlPacket::Entry::operator[](const std::string &name) const {
- std::map<std::string, Element*>::const_iterator it = elements.find(name);
- if(it != elements.end())
- return *it->second;
+template <>
+const std::string& XmlPacket::Entry::get<const std::string&>(const std::string &name) const {
+ static std::string empty;
- std::map<std::string, List*>::const_iterator it2 = lists.find(name);
- if(it2 != lists.end())
- return *it2->second;
+ Element *element = getElement(name);
+ if(!element)
+ return empty;
- return nilElement;
+ return element->str;
}
-bool XmlPacket::Entry::addBinary(const std::string &name, const void *data, size_t size) {
- if(!entryNode)
- return false;
+template <>
+std::vector<boost::uint8_t> XmlPacket::Entry::get<std::vector<unsigned char> >(const std::string &name) const {
+ Element *element = getElement(name);
+ if(!element)
+ return std::vector<boost::uint8_t>();
+
+ switch(element->type) {
+ case Element::BINARY:
+ return boost::get<std::vector<boost::uint8_t> >(element->value);
+ default:
+ return std::vector<boost::uint8_t>();
+ }
+}
- if(elements.find(name) != elements.end() || lists.find(name) != lists.end())
- return false;
+template <>
+const std::vector<boost::uint8_t>& XmlPacket::Entry::get<const std::vector<unsigned char>&>(const std::string &name) const {
+ static std::vector<boost::uint8_t> empty;
- std::string base64Data = Base64Encoder::encode(std::vector<boost::uint8_t>((boost::uint8_t*)data, ((boost::uint8_t*)data)+size));;
+ Element *element = getElement(name);
+ if(!element)
+ return empty;
- return add(name, base64Data, "binary");
+ switch(element->type) {
+ case Element::BINARY:
+ return boost::get<std::vector<boost::uint8_t> >(element->value);
+ default:
+ return empty;
+ }
}
-XmlPacket::List::List(xmlNodePtr node) : Element(node, LIST) {
+XmlPacket::List::List(xmlNodePtr node) : elementNode(node) {
for(xmlNodePtr entry = node->children; entry != 0; entry = entry->next) {
if(entry->type != XML_ELEMENT_NODE || xmlStrcmp(entry->name, (xmlChar*)"entry"))
continue;
@@ -228,11 +228,6 @@ XmlPacket::List::List(xmlNodePtr node) : Element(node, LIST) {
}
}
-XmlPacket::List::~List() {
- for(std::vector<Entry*>::iterator entry = entries.begin(); entry != entries.end(); ++entry)
- delete *entry;
-}
-
XmlPacket::XmlPacket() {
doc = xmlNewDoc((xmlChar*)"1.0");
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;
+
}
}