a8/a8/xvalue.cc
2018-10-31 10:25:36 +08:00

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;
}
}