summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-03-02 17:24:23 +0100
committerMatthias Schiffer <matthias@gamezock.de>2009-03-02 17:24:23 +0100
commit262ef86c7ef317698d56a2fde83ea63b54254893 (patch)
tree350262724cccc23c8b79f97656c0e1dab478ffa1 /src
parente081cc2b3528ce608ee3fa9769d9e4cd59cc3535 (diff)
downloadmad-262ef86c7ef317698d56a2fde83ea63b54254893.tar
mad-262ef86c7ef317698d56a2fde83ea63b54254893.zip
Binaerdaten in XmlPacket
Diffstat (limited to 'src')
-rw-r--r--src/Common/XmlPacket.cpp96
-rw-r--r--src/Common/XmlPacket.h75
2 files changed, 137 insertions, 34 deletions
diff --git a/src/Common/XmlPacket.cpp b/src/Common/XmlPacket.cpp
index 672d092..87045a8 100644
--- a/src/Common/XmlPacket.cpp
+++ b/src/Common/XmlPacket.cpp
@@ -17,8 +17,15 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <config.h>
+
#include "XmlPacket.h"
#include <cstdlib>
+#include <cstring>
+
+extern "C" {
+#include "base64.h"
+}
namespace Mad {
namespace Common {
@@ -30,7 +37,13 @@ void XmlPacket::Element::updateStr() {
if(type == NONE || type == LIST)
return;
- if(type != STRING) {
+ if(type == BINARY) {
+ char *base64Data;
+ base64_encode_alloc((char*)binData, value.var_size, &base64Data);
+ str = base64Data;
+ std::free(base64Data);
+ }
+ else if(type != STRING) {
std::ostringstream buf;
switch(type) {
@@ -56,7 +69,6 @@ void XmlPacket::Element::updateStr() {
buf << value.var_ldouble;
default:
break;
-
}
str = buf.str();
@@ -69,7 +81,7 @@ void XmlPacket::Element::updateStr() {
xmlFreeNode(oldNode);
}
-XmlPacket::Element::Element(xmlNodePtr node) : elementNode(node), type(NONE) {
+XmlPacket::Element::Element(xmlNodePtr node) : elementNode(node), binData(0), type(NONE) {
if(!node)
return;
@@ -85,7 +97,11 @@ XmlPacket::Element::Element(xmlNodePtr node) : elementNode(node), type(NONE) {
str = (char*)content;
- if(!xmlStrcmp(typestr, (xmlChar*)"int")) {
+ if(!xmlStrcmp(typestr, (xmlChar*)"binary")) {
+ type = BINARY;
+ base64_decode_alloc((char*)content, xmlStrlen(content), (char**)&binData, &value.var_size);
+ }
+ else if(!xmlStrcmp(typestr, (xmlChar*)"int")) {
type = INT;
value.var_int = std::strtol((char*)content, 0, 10);
}
@@ -123,6 +139,24 @@ XmlPacket::Element::Element(xmlNodePtr node) : elementNode(node), type(NONE) {
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();
+}
+
XmlPacket::Entry::Entry(xmlNodePtr node) : entryNode(node) {
if(!node)
return;
@@ -134,47 +168,79 @@ XmlPacket::Entry::Entry(xmlNodePtr node) : entryNode(node) {
xmlChar *name = xmlGetProp(element, (xmlChar*)"name");
if(!xmlStrcmp(element->name, (xmlChar*)"list"))
- lists.insert(std::make_pair(std::string((char*)name), List(element)));
+ lists.insert(std::make_pair(std::string((char*)name), new List(element)));
else if(!xmlStrcmp(element->name, (xmlChar*)"value"))
- elements.insert(std::make_pair(std::string((char*)name), Element(element)));
+ elements.insert(std::make_pair(std::string((char*)name), new Element(element)));
xmlFree(name);
}
}
+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);
+ std::map<std::string, Element*>::iterator it = elements.find(name);
if(it != elements.end())
- return it->second;
+ return *it->second;
- std::map<std::string, List>::iterator it2 = lists.find(name);
+ std::map<std::string, List*>::iterator it2 = lists.find(name);
if(it2 != lists.end())
- return it2->second;
+ return *it2->second;
return nilElement;
}
const XmlPacket::Element& XmlPacket::Entry::operator[](const std::string &name) const {
- std::map<std::string, Element>::const_iterator it = elements.find(name);
+ std::map<std::string, Element*>::const_iterator it = elements.find(name);
if(it != elements.end())
- return it->second;
+ return *it->second;
- std::map<std::string, List>::const_iterator it2 = lists.find(name);
+ std::map<std::string, List*>::const_iterator it2 = lists.find(name);
if(it2 != lists.end())
- return it2->second;
+ return *it2->second;
return nilElement;
}
+bool XmlPacket::Entry::addBinary(const std::string &name, const void *data, size_t size) {
+ if(!entryNode)
+ return false;
+
+ if(elements.find(name) != elements.end() || lists.find(name) != lists.end())
+ return false;
+
+ char *base64Data;
+
+ base64_encode_alloc((const char*)data, size, &base64Data);
+ if(!base64Data)
+ return false;
+
+ bool ret = add(name, std::string(base64Data), "binary");
+
+ std::free(base64Data);
+
+ return ret;
+}
+
XmlPacket::List::List(xmlNodePtr node) : Element(node, LIST) {
for(xmlNodePtr entry = node->children; entry != 0; entry = entry->next) {
if(entry->type != XML_ELEMENT_NODE || xmlStrcmp(entry->name, (xmlChar*)"entry"))
continue;
- entries.push_back(Entry(entry));
+ entries.push_back(new Entry(entry));
}
}
+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 e32893a..196da24 100644
--- a/src/Common/XmlPacket.h
+++ b/src/Common/XmlPacket.h
@@ -43,11 +43,10 @@ class XmlPacket {
Entry *entry;
public:
-
class Element {
public:
enum Type {
- NONE, LIST,
+ NONE, LIST, BINARY,
INT, UINT, INT64, UINT64,
FLOAT, DOUBLE, LONGDOUBLE, STRING
};
@@ -58,7 +57,12 @@ class XmlPacket {
xmlNodePtr elementNode;
private:
+ // Prevent shallow copy
+ Element(const Element &o);
+ Element& operator=(const Element &o);
+
std::string str;
+ void *binData;
Type type;
union Variant {
@@ -71,6 +75,8 @@ class XmlPacket {
float var_float;
double var_double;
long double var_ldouble;
+
+ size_t var_size;
} value;
static Entry nilEntry;
@@ -109,11 +115,13 @@ class XmlPacket {
void updateStr();
protected:
- Element(xmlNodePtr node, Type type0) : elementNode(node), type(type0) {}
+ Element(xmlNodePtr node, Type type0) : elementNode(node), binData(0), type(type0) {}
public:
Element(xmlNodePtr node);
+ virtual ~Element();
+
Type getType() const {
return type;
}
@@ -221,16 +229,33 @@ class XmlPacket {
return *this;
}
+
+ 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;
+ }
+ }
};
class Entry {
private:
friend class List;
+ // Prevent shallow copy
+ Entry(const Entry &o);
+ Entry& operator=(const Entry &o);
+
xmlNodePtr entryNode;
- std::map<std::string, Element> elements;
- std::map<std::string, List> lists;
+ std::map<std::string, Element*> elements;
+ std::map<std::string, List*> lists;
static Element nilElement;
@@ -245,7 +270,7 @@ class XmlPacket {
xmlSetProp(newNode, (xmlChar*)"name", (xmlChar*)name.c_str());
xmlSetProp(newNode, (xmlChar*)"type", (xmlChar*)type);
- if(!elements.insert(std::make_pair(name, Element(newNode))).second) {
+ if(!elements.insert(std::make_pair(name, new Element(newNode))).second) {
xmlUnlinkNode(newNode);
xmlFreeNode(newNode);
@@ -257,6 +282,7 @@ class XmlPacket {
public:
Entry(xmlNodePtr node);
+ virtual ~Entry();
Element& operator[](const std::string &name);
const Element& operator[](const std::string &name) const;
@@ -328,6 +354,8 @@ class XmlPacket {
return add(name, val, "string");
}
+ bool addBinary(const std::string &name, const void *data, size_t size);
+
bool addList(const std::string &name) {
if(!entryNode)
return false;
@@ -338,7 +366,7 @@ class XmlPacket {
xmlNodePtr newNode = xmlNewChild(entryNode, 0, (xmlChar*)"list", 0);
xmlSetProp(newNode, (xmlChar*)"name", (xmlChar*)name.c_str());
- if(!lists.insert(std::make_pair(name, List(newNode))).second) {
+ if(!lists.insert(std::make_pair(name, new List(newNode))).second) {
xmlUnlinkNode(newNode);
xmlFreeNode(newNode);
@@ -349,22 +377,22 @@ class XmlPacket {
}
bool remove(const std::string &name) {
- std::map<std::string, Element>::iterator element = elements.find(name);
+ std::map<std::string, Element*>::iterator element = elements.find(name);
if(element != elements.end()) {
- xmlUnlinkNode(element->second.elementNode);
- xmlFreeNode(element->second.elementNode);
+ xmlUnlinkNode(element->second->elementNode);
+ xmlFreeNode(element->second->elementNode);
elements.erase(element);
return true;
}
- std::map<std::string, List>::iterator list = lists.find(name);
+ std::map<std::string, List*>::iterator list = lists.find(name);
if(list != lists.end()) {
- xmlUnlinkNode(list->second.elementNode);
- xmlFreeNode(list->second.elementNode);
+ xmlUnlinkNode(list->second->elementNode);
+ xmlFreeNode(list->second->elementNode);
lists.erase(list);
@@ -377,21 +405,26 @@ class XmlPacket {
class List : public Element {
private:
- std::vector<Entry> entries;
+ // Prevent shallow copy
+ List(const List &o);
+ List& operator=(const List &o);
+
+ std::vector<Entry*> entries;
public:
List(xmlNodePtr node);
+ virtual ~List();
virtual size_t getSize() const {
return entries.size();
}
virtual Entry& operator[](size_t i) {
- return entries[i];
+ return *entries[i];
}
virtual const Entry& operator[](size_t i) const {
- return entries[i];
+ return *entries[i];
}
virtual bool insertEntry(size_t i) {
@@ -401,7 +434,7 @@ class XmlPacket {
xmlNodePtr newNode = xmlNewNode(0, (xmlChar*)"entry");
xmlAddChild(elementNode, newNode);
- entries.insert(entries.begin()+i, Entry(newNode));
+ entries.insert(entries.begin()+i, new Entry(newNode));
return true;
}
@@ -414,8 +447,8 @@ class XmlPacket {
if(i >= getSize())
return false;
- xmlUnlinkNode(entries[i].entryNode);
- xmlFreeNode(entries[i].entryNode);
+ xmlUnlinkNode(entries[i]->entryNode);
+ xmlFreeNode(entries[i]->entryNode);
entries.erase(entries.begin()+i);
@@ -451,6 +484,10 @@ class XmlPacket {
return entry->add(name, val);
}
+ bool addBinary(const std::string &name, const void *data, size_t size) {
+ return entry->addBinary(name, data, size);
+ }
+
bool addList(const std::string &name) {
return entry->addList(name);
}