485 lines
10 KiB
C++
485 lines
10 KiB
C++
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
#include <a8/a8.h>
|
|
#include <a8/xvalue.h>
|
|
|
|
namespace a8
|
|
{
|
|
|
|
XValue::XValue()
|
|
{
|
|
type_ = XVT_INT;
|
|
value_.int_value = 0;
|
|
data_size_ = 0;
|
|
}
|
|
|
|
XValue::~XValue()
|
|
{
|
|
if (type_ == XVT_STRING && value_.str_value){
|
|
free(value_.str_value);
|
|
}else if (type_ == XVT_WSTRING && value_.wstr_value){
|
|
free(value_.wstr_value);
|
|
}
|
|
value_.int_value = 0;
|
|
}
|
|
|
|
XValue::XValue(const XValue& xv)
|
|
{
|
|
type_ = XVT_INT;
|
|
value_.int_value = 0;
|
|
data_size_ = 0;
|
|
if (xv.Type() == XVT_STRING){
|
|
SetDynData(xv.value_.str_value, xv.data_size_);
|
|
}else if (xv.Type() == XVT_WSTRING){
|
|
Set(xv.value_.wstr_value);
|
|
}else{
|
|
type_ = xv.type_;
|
|
value_ = xv.value_;
|
|
}
|
|
}
|
|
|
|
XValue::XValue(int v)
|
|
{
|
|
type_ = XVT_NULL;
|
|
Set(v);
|
|
}
|
|
|
|
XValue::XValue(unsigned int v)
|
|
{
|
|
type_ = XVT_NULL;
|
|
Set(v);
|
|
}
|
|
|
|
XValue::XValue(long v)
|
|
{
|
|
type_ = XVT_NULL;
|
|
Set(v);
|
|
}
|
|
|
|
XValue::XValue(unsigned long v)
|
|
{
|
|
type_ = XVT_NULL;
|
|
Set(v);
|
|
}
|
|
|
|
XValue::XValue(double v)
|
|
{
|
|
type_ = XVT_FLOAT;
|
|
Set(v);
|
|
}
|
|
|
|
XValue::XValue(const char* v)
|
|
{
|
|
type_ = XVT_NULL;
|
|
Set(v);
|
|
}
|
|
|
|
XValue::XValue(const std::string& v)
|
|
{
|
|
type_ = XVT_NULL;
|
|
SetDynData(v.data(), v.size());
|
|
}
|
|
|
|
XValue::XValue(std::string& v)
|
|
{
|
|
type_ = XVT_NULL;
|
|
SetDynData(v.data(), v.size());
|
|
}
|
|
|
|
XValue::XValue(long long v)
|
|
{
|
|
type_ = XVT_NULL;
|
|
Set(v);
|
|
}
|
|
|
|
XValue::XValue(unsigned long long v)
|
|
{
|
|
type_ = XVT_NULL;
|
|
Set(v);
|
|
}
|
|
|
|
void XValue::Set(void* user_data)
|
|
{
|
|
SetUserData(user_data, 0);
|
|
}
|
|
|
|
void XValue::Set(a8::XValue v)
|
|
{
|
|
*this = v;
|
|
}
|
|
|
|
void XValue::Set(int v)
|
|
{
|
|
OnReset();
|
|
type_ = XVT_INT;
|
|
value_.int_value = v;
|
|
}
|
|
|
|
void XValue::Set(long v)
|
|
{
|
|
OnReset();
|
|
if (sizeof(long) == 8) {
|
|
Set((long long)v);
|
|
} else {
|
|
Set((int)v);
|
|
}
|
|
}
|
|
|
|
void XValue::Set(unsigned int v)
|
|
{
|
|
OnReset();
|
|
if (sizeof(long) == 8) {
|
|
Set((unsigned long long)v);
|
|
} else {
|
|
Set((unsigned int)v);
|
|
}
|
|
}
|
|
|
|
void XValue::Set(unsigned long v)
|
|
{
|
|
OnReset();
|
|
type_ = XVT_UINT;
|
|
value_.int_value = v;
|
|
}
|
|
|
|
void XValue::Set(long long v)
|
|
{
|
|
OnReset();
|
|
type_ = XVT_INT64;
|
|
value_.int_value = v;
|
|
}
|
|
|
|
void XValue::Set(unsigned long long v)
|
|
{
|
|
OnReset();
|
|
type_ = XVT_UINT64;
|
|
value_.int_value = v;
|
|
}
|
|
|
|
void XValue::Set(const char* v)
|
|
{
|
|
if (v){
|
|
SetDynData(v, strlen(v));
|
|
}else{
|
|
SetDynData("", 0);
|
|
}
|
|
}
|
|
|
|
void XValue::Set(const wchar_t* v)
|
|
{
|
|
OnReset();
|
|
type_ = XVT_WSTRING;
|
|
int len = v ? wcslen(v) : 0;
|
|
if (len > 0){
|
|
value_.wstr_value = (wchar_t*)malloc((len + 2) * 2);
|
|
wcscpy(value_.wstr_value, v);
|
|
}else
|
|
value_.wstr_value = nullptr;
|
|
}
|
|
|
|
void XValue::SetDynData(const char* v, unsigned int len)
|
|
{
|
|
OnReset();
|
|
type_ = XVT_STRING;
|
|
data_size_ = len;
|
|
if (len > 0){
|
|
value_.str_value = (char*)malloc(len + 1);
|
|
memmove(value_.str_value, v, len);
|
|
value_.str_value[len] = '\0';
|
|
}else
|
|
value_.str_value = nullptr;
|
|
}
|
|
|
|
void XValue::SetUserData(void *userdata, int datasize)
|
|
{
|
|
OnReset();
|
|
type_ = XVT_USERDATA;
|
|
data_size_ = datasize;
|
|
value_.user_data = userdata;
|
|
}
|
|
|
|
void XValue::Set(double v)
|
|
{
|
|
OnReset();
|
|
type_ = XVT_FLOAT;
|
|
value_.float_value = v;
|
|
}
|
|
|
|
void XValue::SetNull()
|
|
{
|
|
OnReset();
|
|
type_ = XVT_NULL;
|
|
value_.int_value = 0;
|
|
}
|
|
|
|
int XValue::Type() const
|
|
{
|
|
return type_;
|
|
}
|
|
|
|
bool XValue::IsNull()
|
|
{
|
|
return type_ == XVT_NULL;
|
|
}
|
|
|
|
bool XValue::IsNumber()
|
|
{
|
|
return type_ == XVT_INT || type_ == XVT_UINT || type_ == XVT_INT64 ||
|
|
type_ == XVT_UINT64 || type_ == XVT_FLOAT;
|
|
}
|
|
|
|
bool XValue::IsString()
|
|
{
|
|
return type_ == XVT_STRING || type_ == XVT_WSTRING;
|
|
}
|
|
|
|
int XValue::GetInt() const
|
|
{
|
|
return (int)GetInt64();
|
|
}
|
|
|
|
unsigned int XValue::GetUInt() const
|
|
{
|
|
return (unsigned int)GetUInt64();
|
|
}
|
|
|
|
long long XValue::GetInt64() const
|
|
{
|
|
switch(type_){
|
|
case XVT_FLOAT:
|
|
return (long long)value_.float_value;
|
|
break;
|
|
case XVT_STRING:
|
|
return value_.str_value ? strtoll(value_.str_value, NULL, 10) : 0;
|
|
break;
|
|
case XVT_WSTRING:
|
|
return strtoll(GetString().c_str(), NULL, 10);
|
|
break;
|
|
default:
|
|
return value_.int_value;
|
|
}
|
|
}
|
|
|
|
unsigned long long XValue::GetUInt64() const
|
|
{
|
|
switch(type_){
|
|
case XVT_FLOAT:
|
|
return (unsigned long long)value_.float_value;
|
|
break;
|
|
case XVT_STRING:
|
|
{
|
|
unsigned long long ui64 = 0;
|
|
if (value_.str_value){
|
|
sscanf(value_.str_value, "%llu", &ui64);
|
|
}
|
|
return ui64;
|
|
break;
|
|
}
|
|
case XVT_WSTRING:
|
|
{
|
|
unsigned long long ui64 = 0;
|
|
if (value_.str_value){
|
|
sscanf(GetString().c_str(), "%llu", &ui64);
|
|
}
|
|
return ui64;
|
|
break;
|
|
}
|
|
default:
|
|
return (unsigned long long)value_.int_value;
|
|
}
|
|
}
|
|
|
|
double XValue::GetDouble() const
|
|
{
|
|
switch(type_){
|
|
case XVT_FLOAT:
|
|
return value_.float_value;
|
|
break;
|
|
case XVT_STRING:
|
|
{
|
|
double dwV = 0;
|
|
if (value_.str_value){
|
|
if (strstr(value_.str_value, "-")){
|
|
sscanf(value_.str_value, "%lf", &dwV);
|
|
}else{
|
|
sscanf(value_.str_value, "%lf", &dwV);
|
|
}
|
|
}
|
|
return dwV;
|
|
break;
|
|
}
|
|
case XVT_WSTRING:
|
|
{
|
|
double dwV = 0;
|
|
if (value_.wstr_value){
|
|
if (wcsstr(value_.wstr_value, L"-")){
|
|
assert(false);
|
|
}else{
|
|
sscanf(GetString().c_str(), "%lf", &dwV);
|
|
}
|
|
}
|
|
return dwV;
|
|
break;
|
|
}
|
|
default:
|
|
return (double)GetInt64();
|
|
}
|
|
}
|
|
|
|
std::string XValue::GetString() const
|
|
{
|
|
const int BUF_LEN = 56;
|
|
char buf[BUF_LEN + 1];
|
|
switch(type_){
|
|
case XVT_STRING:
|
|
return value_.str_value ? std::string(value_.str_value, data_size_) : std::string();
|
|
break;
|
|
case XVT_WSTRING:
|
|
assert(false);
|
|
break;
|
|
case XVT_FLOAT:
|
|
{
|
|
sprintf(buf, "%.12f", value_.float_value);
|
|
return std::string(buf);
|
|
break;
|
|
}
|
|
case XVT_INT:
|
|
case XVT_INT64:
|
|
{
|
|
sprintf(buf, "%lld", value_.int_value);
|
|
return std::string(buf);
|
|
break;
|
|
}
|
|
case XVT_UINT:
|
|
case XVT_UINT64:
|
|
{
|
|
sprintf(buf, "%llu", (unsigned long long)value_.int_value);
|
|
return std::string(buf);
|
|
break;
|
|
}
|
|
default:
|
|
return std::string();
|
|
}
|
|
}
|
|
|
|
std::wstring XValue::GetWString() const
|
|
{
|
|
if (type_ == XVT_WSTRING){
|
|
return value_.wstr_value ? std::wstring(value_.wstr_value) : std::wstring();
|
|
}else{
|
|
#if 1
|
|
assert(false);
|
|
#else
|
|
return s2ws(GetString());
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void* XValue::GetUserData() const
|
|
{
|
|
return type_ == XVT_USERDATA ? value_.user_data : nullptr;
|
|
}
|
|
|
|
XValue::operator bool() const
|
|
{
|
|
return GetInt() != 0;
|
|
}
|
|
|
|
XValue::operator unsigned char() const
|
|
{
|
|
return GetUInt();
|
|
}
|
|
|
|
XValue::operator short() const
|
|
{
|
|
return GetInt();
|
|
}
|
|
|
|
XValue::operator unsigned short() const
|
|
{
|
|
return GetUInt();
|
|
}
|
|
|
|
XValue::operator int() const
|
|
{
|
|
return GetInt();
|
|
}
|
|
|
|
XValue::operator unsigned int() const
|
|
{
|
|
return GetUInt();
|
|
}
|
|
|
|
XValue::operator long() const
|
|
{
|
|
if (sizeof(long) == 8) {
|
|
return GetInt64();
|
|
} else {
|
|
return GetInt();
|
|
}
|
|
}
|
|
|
|
XValue::operator unsigned long() const
|
|
{
|
|
if (sizeof(long) == 8) {
|
|
return GetUInt64();
|
|
} else {
|
|
return GetUInt();
|
|
}
|
|
}
|
|
|
|
XValue::operator double() const
|
|
{
|
|
return GetDouble();
|
|
}
|
|
|
|
XValue::operator long long() const
|
|
{
|
|
return GetInt64();
|
|
}
|
|
|
|
XValue::operator unsigned long long() const
|
|
{
|
|
return GetUInt64();
|
|
}
|
|
|
|
XValue::operator std::string () const
|
|
{
|
|
return GetString();
|
|
}
|
|
|
|
const a8::XValue& XValue::operator=(const a8::XValue& xv)
|
|
{
|
|
type_ = XVT_INT;
|
|
value_.int_value = 0;
|
|
data_size_ = 0;
|
|
if (xv.Type() == XVT_STRING){
|
|
SetDynData(xv.value_.str_value, xv.data_size_);
|
|
}else if (xv.Type() == XVT_WSTRING){
|
|
Set(xv.value_.wstr_value);
|
|
}else{
|
|
type_ = xv.type_;
|
|
value_ = xv.value_;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
bool XValue::IsUserData()
|
|
{
|
|
return type_ == XVT_USERDATA;
|
|
}
|
|
|
|
void XValue::OnReset()
|
|
{
|
|
if (type_ == XVT_STRING && value_.str_value){
|
|
free(value_.str_value);
|
|
}else if (type_ == XVT_WSTRING && value_.wstr_value){
|
|
free(value_.wstr_value);
|
|
}
|
|
value_.int_value = 0;
|
|
data_size_ = 0;
|
|
}
|
|
|
|
}
|