CubicSDR/src/util/DataTree.h
2015-01-10 11:00:03 -05:00

358 lines
14 KiB
C++
Executable File

#pragma once
/*
* DataElement/DataNode/DataTree -- structured serialization/deserialization system
* designed for the CoolMule project :)
*
Copyright (C) 2003 by Charles J. Cliffe
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#define USE_FASTLZ 0
#include <vector>
#include <map>
#include <set>
#include <string>
#include <sstream>
#include <stack>
#include <iostream>
#include "tinyxml.h"
#if USE_FASTLZ
#include "fastlz.h"
#endif
using namespace std;
/* type defines */
#define DATA_NULL 0
#define DATA_CHAR 1
#define DATA_UCHAR 2
#define DATA_INT 3
#define DATA_UINT 4
#define DATA_LONG 5
#define DATA_ULONG 6
#define DATA_LONGLONG 7
#define DATA_FLOAT 8
#define DATA_DOUBLE 9
#define DATA_LONGDOUBLE 10
#define DATA_STRING 11
#define DATA_STR_VECTOR 12
#define DATA_CHAR_VECTOR 13
#define DATA_UCHAR_VECTOR 14
#define DATA_INT_VECTOR 15
#define DATA_UINT_VECTOR 16
#define DATA_LONG_VECTOR 17
#define DATA_ULONG_VECTOR 18
#define DATA_LONGLONG_VECTOR 19
#define DATA_FLOAT_VECTOR 20
#define DATA_DOUBLE_VECTOR 21
#define DATA_LONGDOUBLE_VECTOR 22
#define DATA_VOID 23
/* map comparison function */
struct string_less : public std::binary_function<std::string,std::string,bool>
{
bool operator()(const std::string& a,const std::string& b) const
{
return a.compare(b) < 0;
}
};
/* int comparison function */
struct int_less : public std::binary_function<int,int,bool>
{
bool operator()(int a,int b) const
{
return a < b;
}
};
/* Data Exceptions */
class DataException
{
private:
string reason;
public:
DataException(const char *why) : reason(why) {}
string what() { return reason; }
operator string() { return reason; }
};
class DataTypeMismatchException : public DataException
{
public:
DataTypeMismatchException(const char *why) : DataException(why) { }
};
class DataInvalidChildException : public DataException
{
public:
DataInvalidChildException(const char *why) : DataException(why) { }
};
class DataElement
{
private:
int data_type;
long data_size;
int unit_size;
char *data_val;
void data_init(long data_size_in);
public:
DataElement();
~DataElement();
int getDataType();
char *getDataPointer();
long getDataSize();
int getUnitSize();
/* set overloads */
void set(const char &char_in);
void set(const unsigned char &uchar_in);
void set(const int &int_in);
void set(const unsigned int &uint_in);
void set(const long &long_in);
void set(const unsigned long &ulong_in);
void set(const long long &llong_in);
void set(const float &float_in);
void set(const double &double_in);
void set(const long double &ldouble_in);
void set(const char *data_in, long size_in); /* voids, file chunks anyone? */
void set(const char *data_in); /* strings, stops at NULL, returns as string */
void set(const string &str_in);
void set(vector<string> &strvect_in);
void set(std::set<string> &strset_in);
void set(vector<char> &charvect_in);
void set(vector<unsigned char> &ucharvect_in);
void set(vector<int> &intvect_in);
void set(vector<unsigned int> &uintvect_in);
void set(vector<long> &longvect_in);
void set(vector<unsigned long> &ulongvect_in);
void set(vector<long long> &llongvect_in);
void set(vector<float> &floatvect_in);
void set(vector<double> &doublevect_in);
void set(vector<long double> &ldoublevect_in);
/* get overloads */
void get(char &char_in) throw (DataTypeMismatchException);
void get(unsigned char &uchar_in) throw (DataTypeMismatchException);
void get(int &int_in) throw (DataTypeMismatchException);
void get(unsigned int &uint_in) throw (DataTypeMismatchException);
void get(long &long_in) throw (DataTypeMismatchException);
void get(unsigned long &ulong_in) throw (DataTypeMismatchException);
void get(long long &long_in) throw (DataTypeMismatchException);
void get(float &float_in) throw (DataTypeMismatchException);
void get(double &double_in) throw (DataTypeMismatchException);
void get(long double &ldouble_in) throw (DataTypeMismatchException);
void get(char **data_in) throw (DataTypeMismatchException); /* getting a void or string */
void get(string &str_in) throw (DataTypeMismatchException);
void get(std::set<string> &strset_in) throw (DataTypeMismatchException);
void get(vector<string> &strvect_in) throw (DataTypeMismatchException);
void get(vector<char> &charvect_in) throw (DataTypeMismatchException);
void get(vector<unsigned char> &ucharvect_in) throw (DataTypeMismatchException);
void get(vector<int> &intvect_in) throw (DataTypeMismatchException);
void get(vector<unsigned int> &uintvect_in) throw (DataTypeMismatchException);
void get(vector<long> &longvect_in) throw (DataTypeMismatchException);
void get(vector<unsigned long> &ulongvect_in) throw (DataTypeMismatchException);
void get(vector<long long> &llongvect_in) throw (DataTypeMismatchException);
void get(vector<float> &floatvect_in) throw (DataTypeMismatchException);
void get(vector<double> &doublevect_in) throw (DataTypeMismatchException);
void get(vector<long double> &ldoublevect_in) throw (DataTypeMismatchException);
/* special get functions, saves creating unnecessary vars */
int getChar() throw (DataTypeMismatchException) { char i_get; get(i_get); return i_get; };
unsigned int getUChar() throw (DataTypeMismatchException) { unsigned char i_get; get(i_get); return i_get; };
int getInt() throw (DataTypeMismatchException) { int i_get; get(i_get); return i_get; };
unsigned int getUInt() throw (DataTypeMismatchException) { unsigned int i_get; get(i_get); return i_get; };
long getLong() throw (DataTypeMismatchException) { long l_get; get(l_get); return l_get; };
unsigned long getULong() throw (DataTypeMismatchException) { unsigned long l_get; get(l_get); return l_get; };
long getLongLong() throw (DataTypeMismatchException) { long long l_get; get(l_get); return l_get; };
float getFloat() throw (DataTypeMismatchException) { float f_get; get(f_get); return f_get; };
double getDouble() throw (DataTypeMismatchException) { double d_get; get(d_get); return d_get; };
long double getLongDouble() throw (DataTypeMismatchException) { long double d_get; get(d_get); return d_get; };
/* serialize functions */
long getSerializedSize();
long getSerialized(char **ser_str);
void setSerialized(char *ser_str);
};
class DataNode
{
private:
DataNode *parentNode;
vector<DataNode *> children;
map<string, vector<DataNode *>, string_less> childmap;
map<string, unsigned int, string_less> childmap_ptr;
string node_name;
DataElement *data_elem;
unsigned int ptr;
public:
DataNode();
DataNode(const char *name_in);
~DataNode();
void setName(const char *name_in);
string &getName() { return node_name; }
DataNode *getParentNode() { return parentNode; };
void setParentNode(DataNode &parentNode_in) { parentNode = &parentNode_in; };
int numChildren(); /* Number of children */
int numChildren(const char *name_in); /* Number of children named 'name_in' */
DataElement *element(); /* DataElement at this node */
DataNode *newChild(const char *name_in);
DataNode *child(const char *name_in, int index = 0) throw (DataInvalidChildException);
DataNode *child(int index) throw (DataInvalidChildException);
bool hasAnother(const char *name_in); /* useful for while() loops in conjunction with getNext() */
bool hasAnother();
DataNode *getNext(const char *name_in) throw (DataInvalidChildException); /* get next of specified name */
DataNode *getNext() throw (DataInvalidChildException); /* get next child */
void rewind(const char *name_in); /* rewind specific */
void rewind(); /* rewind generic */
void findAll(const char *name_in, vector<DataNode *> &node_list_out);
// operator string () { string s; element()->get(s); return s; }
operator const char * () { if (element()->getDataType() == DATA_STRING) return element()->getDataPointer(); else return NULL; }
operator char () { char v; element()->get(v); return v; }
operator unsigned char () { unsigned char v; element()->get(v); return v; }
operator int () { int v; element()->get(v); return v; }
operator unsigned int () { unsigned int v; element()->get(v); return v; }
operator long () { long v; element()->get(v); return v; }
operator unsigned long () { unsigned long v; element()->get(v); return v; }
operator long long () { long long v; element()->get(v); return v; }
operator float () { float v; element()->get(v); return v; }
operator double () { double v; element()->get(v); return v; }
operator long double () { long double v; element()->get(v); return v; }
operator vector<char> () { vector<char> v; element()->get(v); return v; }
operator vector<unsigned char> () { vector<unsigned char> v; element()->get(v); return v; }
operator vector<int> () { vector<int> v; element()->get(v); return v; }
operator vector<unsigned int> () { vector<unsigned int> v; element()->get(v); return v; }
operator vector<long> () { vector<long> v; element()->get(v); return v; }
operator vector<unsigned long> () { vector<unsigned long> v; element()->get(v); return v; }
operator vector<float> () { vector<float> v; element()->get(v); return v; }
operator vector<double> () { vector<double> v; element()->get(v); return v; }
operator vector<long double> () { vector<long double> v; element()->get(v); return v; }
const string &operator= (const string &s) { element()->set(s); return s; }
char operator= (char i) { element()->set(i); return i; }
unsigned char operator= (unsigned char i) { element()->set(i); return i; }
int operator= (int i) { element()->set(i); return i; }
unsigned int operator= (unsigned int i) { element()->set(i); return i; }
long operator= (long i) { element()->set(i); return i; }
unsigned long operator= (unsigned long i) { element()->set(i); return i; }
long long operator= (long long i) { element()->set(i); return i; }
float operator= (float i) { element()->set(i); return i; }
double operator= (double i) { element()->set(i); return i; }
long double operator= (long double i) { element()->set(i); return i; }
vector<char> &operator= (vector<char> &v) { element()->set(v); return v; }
vector<unsigned char> &operator= (vector<unsigned char> &v) { element()->set(v); return v; }
vector<int> &operator= (vector<int> &v) { element()->set(v); return v; }
vector<unsigned int> &operator= (vector<unsigned int> &v) { element()->set(v); return v; }
vector<long> &operator= (vector<long> &v) { element()->set(v); return v; }
vector<unsigned long> &operator= (vector<unsigned long> &v) { element()->set(v); return v; }
vector<float> &operator= (vector<float> &v) { element()->set(v); return v; }
vector<double> &operator= (vector<double> &v) { element()->set(v); return v; }
vector<long double> &operator= (vector<long double> &v) { element()->set(v); return v; }
DataNode *operator[] (const char *name_in) { return getNext(name_in); }
DataNode *operator[] (int idx) { return child(idx); }
bool operator() (const char *name_in) { return hasAnother(name_in); }
bool operator() () { return hasAnother(); }
DataNode *operator ^(const char *name_in) { return newChild(name_in); }
};
typedef vector<DataNode *> DataNodeList;
enum DT_FloatingPointPolicy {
USE_FLOAT,
USE_DOUBLE
};
class DataTree
{
private:
DataNode dn_root;
public:
DataTree(const char *name_in);
DataTree();
~DataTree();
DataNode *rootNode();
void nodeToXML(DataNode *elem, TiXmlElement *elxml);
void setFromXML(DataNode *elem, TiXmlNode *elxml, bool root_node=true, DT_FloatingPointPolicy fpp=USE_FLOAT);
void decodeXMLText(DataNode *elem, const char *in_text, DT_FloatingPointPolicy fpp);
void printXML(); /* print datatree as XML */
long getSerializedSize(DataElement &de_node_names, bool debug=false); /* get serialized size + return node names header */
long getSerialized(char **ser_str, bool debug=false);
void setSerialized(char *ser_str, bool debug=false);
bool LoadFromFileXML(const std::string& filename, DT_FloatingPointPolicy fpp=USE_FLOAT);
bool SaveToFileXML(const std::string& filename);
// bool SaveToFile(const std::string& filename);
// bool LoadFromFile(const std::string& filename);
bool SaveToFile(const std::string& filename, bool compress = true, int compress_level = 2);
bool LoadFromFile(const std::string& filename);
};