Commit 96bba8f3 authored by gladish's avatar gladish
Browse files

Finished up some Variant work.

parent a01a0641
#include "Variant.h"
namespace
{
}
common::Variant::Data::Data()
{
Type = DataType::Invalid;
memset(&Item, 0, sizeof(m_data.Item));
Size = 0;
}
common::Variant::Variant()
: m_type(DataType::Invalid)
: m_data()
{
memset(&m_data, 0, sizeof(m_data));
}
common::Variant::Variant(bool b)
: m_type(DataType::Boolean)
: m_data()
{
m_data.v_bool = b;
m_data.Type = DataType::Boolean;
m_data.Item.v_bool = b;
}
common::Variant::Variant(std::vector<bool> const& v)
: m_data()
{
m_data.Type = DataType::BooleanArray;
AllocAndCopy(m_data, v);
}
common::Variant::Variant(uint8_t y)
: m_type(DataType::UInt8)
: m_data()
{
m_data.Type = DataType::UInt8;
m_data.Item.v_uint8 = y;
}
common::Variant::Variant(std::vector<uint8_t> const& v)
: m_data()
{
m_data.v_uint8 = y;
m_data.Type = DataType::UInt8Array;
AllocAndCopy(m_data, v);
}
common::Variant::Variant(int16_t n)
: m_type(DataType::Int16)
: m_data()
{
m_data.v_int16 = n;
m_data.Type = DataType::Int16;
m_data.Item.v_int16 = n;
}
common::Variant::Variant(std::vector<uint16_t> const& v)
: m_data()
{
m_data.Type = DataType::UInt16Array;
AllocAndCopy(m_data, v);
}
common::Variant::Variant(uint16_t q)
: m_type(DataType::UInt16)
: m_data()
{
m_data.Type = DataType::UInt16;
m_data.Item.v_uint16 = q;
}
common::Variant::Variant(std::vector<int16_t> const& v)
: m_data()
{
m_data.v_uint16 = q;
m_data.Type = DataType::Int16Array;
AllocAndCopy(m_data, v);
}
common::Variant::Variant(int32_t i)
: m_type(DataType::Int32)
: m_data()
{
m_data.v_int32 = i;
m_data.Type = DataType::Int32;
m_data.Item.v_int32 = i;
}
common::Variant::Variant(std::vector<int32_t> const& v)
: m_data()
{
m_data.Type = DataType::Int32Array;
AllocAndCopy(m_data, v);
}
common::Variant::Variant(uint32_t u)
: m_type(DataType::UInt32)
: m_data()
{
m_data.Type = DataType::UInt32;
m_data.Item.v_uint32 = u;
}
common::Variant::Variant(std::vector<uint32_t> const& v)
: m_data()
{
m_data.v_uint32 = u;
m_data.Type = DataType::UInt32Array;
AllocAndCopy(m_data, v);
}
common::Variant::Variant(int64_t x)
: m_type(DataType::Int64)
: m_data()
{
m_data.v_int64 = x;
m_data.Type = DataType::Int64;
m_data.Item.v_int64 = x;
}
common::Variant::Variant(std::vector<int64_t> const& v)
: m_data()
{
m_data.Type = DataType::Int64Array;
AllocAndCopy(m_data, v);
}
common::Variant::Variant(uint64_t t)
: m_type(DataType::UInt64)
: m_data()
{
m_data.Type = DataType::UInt64;
m_data.Item.v_uint64 = t;
}
common::Variant::Variant(std::vector<uint64_t> const& v)
: m_data()
{
m_data.v_uint64 = t;
m_data.Type = DataType::UInt64Array;
AllocAndCopy(m_data, v);
}
common::Variant::Variant(double d)
: m_type(DataType::Double)
: m_data()
{
m_data.v_double = d;
m_data.Type = DataType::Double;
m_data.Item.v_double = d;
}
common::Variant::Variant(std::vector<double> const& v)
: m_data()
{
m_data.Type = DataType::DoubleArray;
AllocAndCopy(m_data, v);
}
common::Variant::Variant(DataType t)
: m_type(t)
: m_data()
{
memset(&m_data, 0, sizeof(m_data));
m_data.Type = t;
}
common::Variant::Variant(std::string const& s)
: m_type(DataType::String)
: m_data()
{
if (!m_data.v_string)
m_data.v_string = new std::string();
*m_data.v_string = s;
m_data.Type = DataType::String;
if (!m_data.Item.v_string)
m_data.Item.v_string = new std::string();
*m_data.Item.v_string = s;
}
common::Variant::Variant(char const* s)
: m_type(DataType::String)
: m_data()
{
m_data.Type = DataType::String;
if (s)
{
if (!m_data.v_string)
m_data.v_string = new std::string();
*m_data.v_string = s;
if (!m_data.Item.v_string)
m_data.Item.v_string = new std::string();
*m_data.Item.v_string = s;
}
}
common::Variant::Variant(std::vector<std::string> const& v)
: m_data()
{
m_data.Type = DataType::StringArray;
AllocAndCopy(m_data, v);
}
common::Variant::Variant(Variant const& other)
{
AssignFrom(other);
......@@ -92,8 +184,11 @@ common::Variant::Variant(Variant const& other)
common::Variant::~Variant()
{
if (m_type == DataType::String && m_data.v_string)
delete m_data.v_string;
if (m_data.Item.v_string)
delete m_data.Item.v_string;
if (m_data.Item.v_arr)
free(m_data.Item.v_arr);
}
common::Variant&
......@@ -109,96 +204,138 @@ common::Variant::operator=(Variant const& other)
std::vector<bool>
common::Variant::ToBooleanArray(bool* ok) const
{
return std::vector<bool>();
return GetArray<bool>(DataType::BooleanArray, ok);
}
std::vector<uint8_t>
common::Variant::ToUInt8Array(bool* ok) const
{
return std::vector<uint8_t>();
return GetArray<uint8_t>(DataType::UInt8Array, ok);
}
std::vector<int16_t>
common::Variant::ToInt16Array(bool* ok) const
{
return std::vector<int16_t>();
return GetArray<int16_t>(DataType::Int16Array, ok);
}
std::vector<uint16_t>
common::Variant::ToUInt16Array(bool* ok) const
{
return std::vector<uint16_t>();
return GetArray<uint16_t>(DataType::UInt16Array, ok);
}
std::vector<int32_t>
common::Variant::ToInt32Array(bool* ok) const
{
return std::vector<int32_t>();
return GetArray<int32_t>(DataType::Int32Array, ok);
}
std::vector<uint32_t>
common::Variant::ToUInt32Array(bool* ok) const
{
return std::vector<uint32_t>();
return GetArray<uint32_t>(DataType::UInt32Array, ok);
}
std::vector<int64_t>
common::Variant::ToInt64Array(bool* ok) const
{
return std::vector<int64_t>();
return GetArray<int64_t>(DataType::Int64Array, ok);
}
std::vector<uint64_t>
common::Variant::ToUInt64Array(bool* ok) const
{
return std::vector<uint64_t>();
return GetArray<uint64_t>(DataType::UInt64Array, ok);
}
std::vector<double>
common::Variant::ToDoubleArray(bool* ok) const
{
return std::vector<double>();
return GetArray<double>(DataType::DoubleArray, ok);
}
std::vector<std::string>
common::Variant::ToStringArray(bool* ok) const
{
return std::vector<std::string>();
return GetArray<std::string>(DataType::StringArray, ok);
}
void
common::Variant::AssignFrom(Variant const& other)
{
switch (other.m_type)
switch (other.m_data.Type)
{
case DataType::Invalid: break;
case DataType::Boolean: m_data.v_bool = other.m_data.v_bool; break;
case DataType::UInt8: m_data.v_uint8 = other.m_data.v_uint8; break;
case DataType::Int16: m_data.v_int16 = other.m_data.v_int16; break;
case DataType::UInt16: m_data.v_uint16 = other.m_data.v_uint16; break;
case DataType::Int32: m_data.v_int32 = other.m_data.v_int32; break;
case DataType::UInt32: m_data.v_uint32 = other.m_data.v_uint32; break;
case DataType::Int64: m_data.v_int64 = other.m_data.v_int64; break;
case DataType::UInt64: m_data.v_uint64 = other.m_data.v_uint64; break;
case DataType::Double: m_data.v_double = other.m_data.v_double; break;
case DataType::Boolean: m_data.Item.v_bool = other.m_data.Item.v_bool; break;
case DataType::UInt8: m_data.Item.v_uint8 = other.m_data.Item.v_uint8; break;
case DataType::Int16: m_data.Item.v_int16 = other.m_data.Item.v_int16; break;
case DataType::UInt16: m_data.Item.v_uint16 = other.m_data.Item.v_uint16; break;
case DataType::Int32: m_data.Item.v_int32 = other.m_data.Item.v_int32; break;
case DataType::UInt32: m_data.Item.v_uint32 = other.m_data.Item.v_uint32; break;
case DataType::Int64: m_data.Item.v_int64 = other.m_data.Item.v_int64; break;
case DataType::UInt64: m_data.Item.v_uint64 = other.m_data.Item.v_uint64; break;
case DataType::Double: m_data.Item.v_double = other.m_data.Item.v_double; break;
case DataType::String:
{
if (other.m_data.v_string)
if (other.m_data.Item.v_string)
{
if (!m_data.v_string)
m_data.v_string = new std::string();
*m_data.v_string = *other.m_data.v_string;
if (!m_data.Item.v_string)
m_data.Item.v_string = new std::string();
*m_data.Item.v_string = *other.m_data.Item.v_string;
}
}
break;
// arrays
case DataType::BooleanArray:
AssignFromArray<bool>(m_data, other.m_data);
break;
case DataType::UInt8Array:
AssignFromArray<uint8_t>(m_data, other.m_data);
break;
case DataType::Int16Array:
AssignFromArray<int16_t>(m_data, other.m_data);
break;
case DataType::UInt16Array:
AssignFromArray<uint16_t>(m_data, other.m_data);
break;
case DataType::Int32Array:
AssignFromArray<int32_t>(m_data, other.m_data);
break;
case DataType::UInt32Array:
AssignFromArray<uint32_t>(m_data, other.m_data);
break;
case DataType::Int64Array:
AssignFromArray<int64_t>(m_data, other.m_data);
break;
case DataType::UInt64Array:
AssignFromArray<uint64_t>(m_data, other.m_data);
break;
case DataType::DoubleArray:
AssignFromArray<double>(m_data, other.m_data);
break;
case DataType::StringArray:
AssignFromArray<std::string>(m_data, other.m_data);
break;
}
m_type = other.m_type;
m_data.Type = other.m_data.Type;
}
bool
common::Variant::CanConvert(DataType t) const
{
return m_type == t;
// TODO: better type conversion
return m_data.Type == t;
}
std::string
......@@ -208,11 +345,13 @@ common::Variant::ToString(bool* ok) const
// to be converted later.
if (CanConvert(DataType::String))
{
if (ok) *ok = true;
if (m_data.v_string) return *m_data.v_string;
if (ok)
*ok = true;
if (m_data.Item.v_string)
return *m_data.Item.v_string;
return std::string();
}
if (ok) *ok = false;
if (ok)
*ok = false;
return std::string();
}
......@@ -35,7 +35,7 @@ namespace common
Int64Array,
UInt64Array,
DoubleArray,
StringArray,
StringArray
};
Variant();
......@@ -53,12 +53,23 @@ namespace common
Variant(std::string const& s);
Variant(Variant const& other);
Variant(std::vector<bool> const& v);
Variant(std::vector<uint8_t> const& v);
Variant(std::vector<int16_t> const& v);
Variant(std::vector<uint16_t> const& v);
Variant(std::vector<int32_t> const& v);
Variant(std::vector<uint32_t> const& v);
Variant(std::vector<int64_t> const& v);
Variant(std::vector<uint64_t> const& v);
Variant(std::vector<double> const& v);
Variant(std::vector<std::string> const& v);
Variant& operator=(Variant const& other);
~Variant();
inline DataType GetType() const
{ return m_type; }
{ return m_data.Type; }
inline bool ToBoolean(bool* ok = NULL) const
{ return Get<bool>(DataType::Boolean, ok); }
......@@ -109,15 +120,15 @@ namespace common
// no conversion for now
switch (t)
{
case DataType::Boolean: return m_data.v_bool;
case DataType::UInt8: return m_data.v_uint8;
case DataType::Int16: return m_data.v_int16;
case DataType::UInt16: return m_data.v_uint16;
case DataType::Int32: return m_data.v_int32;
case DataType::UInt32: return m_data.v_uint32;
case DataType::Int64: return m_data.v_int64;
case DataType::UInt64: return m_data.v_uint64;
case DataType::Double: return m_data.v_double;
case DataType::Boolean: return m_data.Item.v_bool;
case DataType::UInt8: return m_data.Item.v_uint8;
case DataType::Int16: return m_data.Item.v_int16;
case DataType::UInt16: return m_data.Item.v_uint16;
case DataType::Int32: return m_data.Item.v_int32;
case DataType::UInt32: return m_data.Item.v_uint32;
case DataType::Int64: return m_data.Item.v_int64;
case DataType::UInt64: return m_data.Item.v_uint64;
case DataType::Double: return m_data.Item.v_double;
default:
DSB_ASSERT(false);
break;
......@@ -137,10 +148,25 @@ namespace common
*ok = false;
return T();
}
DataType m_type;
union {
template<class T>
std::vector<T> GetArray(DataType t, bool *ok) const
{
if (CanConvert(t))
{
T* arr = (T *) m_data.Item.v_arr;
std::vector<T> v;
for (int i = 0; i < m_data.Size; ++i)
v.push_back(arr[i]);
return v;
}
if (ok)
*ok = false;
return std::vector<T>();
}
union DataItem {
bool v_bool;
uint8_t v_uint8;
int16_t v_int16;
......@@ -151,8 +177,58 @@ namespace common
uint64_t v_uint64;
double v_double;
std::string* v_string;
} m_data;
// all arrays are stashed here
void* v_arr;
};
struct Data
{
DataType Type;
DataItem Item;
int Size;
Data();
};
Data m_data;
void AssignFrom(Variant const& other);
template<class T>
void AssignFromArray(Data& to, Data const& from)
{
if (to.Item.v_arr)
free(to.Item.v_arr);
to.Item.v_arr = malloc(sizeof(T) * from.Size);
T* toVect = reinterpret_cast<T *>(to.Item.v_arr);
T* fromVect = reinterpret_cast<T *>(from.Item.v_arr);
for (int i = 0; i < to.Size; ++i)
toVect[i] = fromVect[i];
}
template<class T>
void AllocAndCopy(common::Variant::Data& d, std::vector<T> const& v)
{
d.Size = static_cast<int>(v.size());
if (d.Size > 0)
{
if (d.Item.v_arr)
free(d.Item.v_arr);
d.Item.v_arr = malloc(sizeof(T) * d.Size);
T* arr = reinterpret_cast<T *>(d.Item.v_arr);
for (int i = 0; i < d.Size; ++i)
arr[i] = v[i];
}
else
{
d.Item.v_arr = NULL;
}
}
};
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment