#include #include #include #include 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(void* userdata) { type_ = XVT_NULL; Set(userdata); } 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 std::string& v) { SetDynData(v.data(), v.size()); } 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; } void XValue::DeepCopy(a8::XValue& to) { to = *this; } 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) { if (type_ == XVT_STRING && value_.str_value){ free(value_.str_value); }else if (type_ == XVT_WSTRING && value_.wstr_value){ free(value_.wstr_value); } 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; } }