//#include "StdAfx.h" #define BOOST_SPIRIT_THREADSAFE #include "ResDataObject.h" #include #include #include #include #include #include #include #include "CommonFun.h" #define CRTDBG_MAP_ALLOC #include #include //#include #include #include #include using namespace boost::property_tree; //general data object-------------------------------------- std::string wc2mb( const wchar_t* wcstr) { std::wstring_convert> conv; std::string strVal = conv.to_bytes(wcstr); // 将宽字符字符串转换为UTF-8编码的多字节字符串 return strVal; } std::wstring mb2wc(const char* mbstr) { std::wstring_convert> conv; std::wstring strVal = conv.from_bytes(mbstr); // 将多字节字符串转换为宽字符字符串 return strVal; } // // // //std::string tostring(const wchar_t *pKey) //{ // std::string temp; // temp = wc2mb(pKey); // // return temp; // //} // // //std::string tostring(const char *pKey) //{ // std::string temp; // temp = pKey; // // return temp; // //} // //std::wstring towstring(const wchar_t *pKey) //{ // std::wstring temp; // temp = pKey; // // return temp; //} // //std::wstring towstring(const char *pKey) //{ // std::wstring temp; // temp = mb2wc(pKey); // // return temp; //} //---------------------------------------------------------------------------------------------- template bool StrToIntegerT(const char * str, Type *result) { Type value = 0; Type sign = 1; Type radix; if (str == NULL) { return false; } if (strlen(str) == 0) { return false; } if (*str == '-') { sign = -1; str++; } if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X')) { radix = 16; str += 2; } //else if(*str == '0') //{ // radix = 8; // str++; //} else { radix = 10; } while (*str) { if (radix == 16) { if (*str >= '0' && *str <= '9') { value = value * radix + *str - '0'; } else { if ((*str | 0x20) >= 'a' && (*str | 0x20) <= 'f') { value = value * radix + (*str | 0x20) - 'a' + 10; } else { return false; } } } else { value = value * radix + *str - '0'; } str++; } *result = sign*value; return true; }; bool PrintBoostPtObject(ptree &pt,const char *pParentKey) { for (boost::property_tree::ptree::iterator it = pt.begin(); it != pt.end(); it++) { boost::property_tree::ptree subPt = it->second; size_t Count = subPt.size(); ResDataObject subObject; if (Count == 0) { //if (pParentKey) //{ // printf("parent[%s]:it[%s]:sub[%s]\n", pParentKey, it->first.c_str(), subPt.data().c_str()); //} //else //{ // printf("parent[NULL]:it[%s]:sub[%s]\n", it->first.c_str(), subPt.data().c_str()); //} continue; } //we got more sub pts if (PrintBoostPtObject(subPt,it->first.c_str()) == false) { return false; } } return true; } bool ParsePtToDataObject(ResDataObject &obj,ptree &pt) { for (boost::property_tree::ptree::iterator it = pt.begin(); it!=pt.end(); it++) { boost::property_tree::ptree subPt = it->second; size_t Count = subPt.size(); ResDataObject subObject; if(Count == 0) { subObject = (subPt.data().c_str()); if (obj.add(it->first.c_str(), subObject) == false) { return false; } continue; } //we got more sub pts if(ParsePtToDataObject(subObject,subPt) == false) { return false; } if (obj.add(it->first.c_str(), subObject) == false) { return false; } } return true; } bool ParseDataObjectToPt(ptree& pt, ResDataObject& obj) { auto recursive_parse = [&](auto& self, ptree& current_pt, ResDataObject& current_obj, int depth) -> bool { // 增强的空对象检查 if (!current_obj.IsObject() || current_obj.size() == 0) { return true; } if (depth > 100) { // 降低深度限制到更安全的100层 std::cerr << "Recursion depth limit exceeded (100)" << std::endl; return false; } const size_t objSize = current_obj.size(); for (size_t i = 0; i < objSize; ++i) { // 双重索引验证 if (i >= objSize || i >= current_obj.size()) { std::cerr << "Index " << i << " out of range (size: " << current_obj.size() << ")" << std::endl; return false; } try { const char* key = current_obj.GetKey(i); if (!key || *key == '\0') { std::cerr << "Depth " << depth << ": Invalid key at index " << i << " (size: " << current_obj.size() << ")" << std::endl; // 跳过无效键而不是中止整个解析 continue; } ResDataObject& child = current_obj[i]; // 更健壮的类型检查 if (child.IsObject() && child.size() > 0) { ptree subpt; if (!self(self, subpt, child, depth + 1)) { std::cerr << "Depth " << depth << ": Failed parsing nested object '" << key << "' (size: " << child.size() << ")" << std::endl; return false; } current_pt.add_child(key, subpt); } else { try { // 安全的类型转换 const char* value = static_cast(child); current_pt.put(key, value ? value : ""); } catch (...) { current_pt.put(key, ""); } } } catch (const ResDataObjectExption& e) { std::cerr << "Depth " << depth << ": Exception at index " << i << ": " << e.what() << std::endl; return false; } catch (const std::exception& e) { std::cerr << "Depth " << depth << ": Std exception at index " << i << ": " << e.what() << std::endl; return false; } catch (...) { std::cerr << "Depth " << depth << ": Unknown exception at index " << i << std::endl; return false; } } return true; }; // 初始调用添加保护 try { return recursive_parse(recursive_parse, pt, obj, 0); } catch (...) { std::cerr << "Top-level exception in ParseDataObjectToPt" << std::endl; return false; } } ResDataObjectExption::ResDataObjectExption(const char *pExp) : m_ExpContext(std::make_unique(pExp ? pExp : "")) {} ResDataObjectExption::ResDataObjectExption(const ResDataObjectExption &tValue) : m_ExpContext(std::make_unique(*tValue.m_ExpContext)) {} ResDataObjectExption::~ResDataObjectExption(void) = default; const char *ResDataObjectExption::what() const { if(m_ExpContext->size() == 0) { (*m_ExpContext) = " "; } return m_ExpContext->c_str(); } ResDataObjectExption& ResDataObjectExption::operator = (const ResDataObjectExption &tValue) { if (this != &tValue) { (*m_ExpContext) = (*(tValue.m_ExpContext)); } return (*this); } ResDataObject_Pair::ResDataObject_Pair() : first(std::make_unique()), second(std::make_unique()) {} ResDataObject_Pair::ResDataObject_Pair(const ResDataObject_Pair& other) : first(std::make_unique(*other.first)), second(std::make_unique(*other.second)) { } ResDataObject_Pair& ResDataObject_Pair::operator=(const ResDataObject_Pair& other) { if (this != &other) { *first = *other.first; *second = *other.second; } return *this; } ResDataObject_Pair& ResDataObject_Pair::operator=(ResDataObject_Pair&& other) noexcept { if (this != &other) { first = std::move(other.first); second = std::move(other.second); // 确保源对象处于有效状态(与移动构造逻辑一致) if (!other.first) { other.first = std::make_unique(); } if (!other.second) { other.second = std::make_unique(); } } return *this; } ResDataObject::ResDataObject(void) : m_encode(std::make_unique()), m_value(std::make_unique()), m_vec(std::make_unique>()) {} ResDataObject::ResDataObject(const ResDataObject& tValue) : m_encode(std::make_unique(*tValue.m_encode)), m_value(std::make_unique(*tValue.m_value)), m_vec(std::make_unique>()) { m_vec->reserve(tValue.m_vec->size()); for (const auto& pair : *tValue.m_vec) { m_vec->push_back(pair); } //std::cerr << "[ResDataObject] Copied to " << this //<< ", m_vec=" << m_vec.get() << std::endl; } ResDataObject::ResDataObject(ResDataObject&& tValue) noexcept : m_encode(std::move(tValue.m_encode)), m_value(std::move(tValue.m_value)), m_vec(std::move(tValue.m_vec)) { tValue.m_encode = std::make_unique(); tValue.m_value = std::make_unique(); tValue.m_vec = std::make_unique>(); //std::cerr << "[ResDataObject] move to " << this //<< ", m_vec=" << m_vec.get() << std::endl; } ResDataObject::~ResDataObject(void) { } ResDataObject& ResDataObject::operator=(ResDataObject&& tValue) noexcept { if (this != &tValue) { m_encode = std::move(tValue.m_encode); m_value = std::move(tValue.m_value); m_vec = std::move(tValue.m_vec); } if (!tValue.m_vec) { tValue.m_vec = std::make_unique>(); } return *this; } //commons void ResDataObject::clear() { m_encode->clear(); m_value->clear(); m_vec->clear(); } size_t ResDataObject::size() { return m_vec->size(); } bool ResDataObject::IsObject() { return !m_vec->empty(); } const char *ResDataObject::encode() { if (m_vec->empty() && !m_value->empty()) { return m_value->c_str(); } boost::property_tree::ptree pt; if(ParseDataObjectToPt(pt,(*this)) == true) { std::stringstream strm; json_parser::write_json(strm, pt, false); (*m_encode) = strm.str(); return m_encode->c_str(); } throw ResDataObjectExption("encode failed. "); } bool ResDataObject::decode( const char *pdata ) { bool IsJsonStr = false; size_t i = 0; while (pdata[i] != 0) { if (pdata[i] == ':') { IsJsonStr = true; break; } ++i; } if (pdata && strlen(pdata) > 0) { if (IsJsonStr) { std::stringstream strm; strm << pdata; ptree pt; try { json_parser::read_json(strm, pt); clear(); return ParsePtToDataObject(*this, pt); } catch (...) { throw ResDataObjectExption("decode failed. "); return false; } } else { (*this) = pdata; } } else { (*this) = ""; } return true; } bool ResDataObject::DumpJsonFile(const char *pfileName) { if (pfileName == 0) { throw ResDataObjectExption("open file failed"); return false; } ptree pt; std::string fileName = (pfileName); if (fileName.size() == 0) { throw ResDataObjectExption("file name is empty"); return false; } try { std::string filenameLow = fileName; std::transform(filenameLow.begin(), filenameLow.end(), filenameLow.begin(), [](unsigned char c) { return std::tolower(c); }); static const basic_string ::size_type npos = -1; basic_string ::size_type foundini = filenameLow.rfind(".ini"); basic_string ::size_type foundxml = filenameLow.rfind(".xml"); basic_string ::size_type foundjson = filenameLow.rfind(".json"); if (foundxml != npos && ((foundxml + strlen(".xml")) == filenameLow.size())) { //found xml file //xml_parser::read_xml(fileName,pt,xml_parser::trim_whitespace|xml_parser::no_comments); xml_parser::read_xml(fileName, pt, xml_parser::no_comments); } else if (foundjson != npos && ((foundjson + strlen(".json")) == filenameLow.size())) { //found json file json_parser::read_json(fileName, pt); } else if (foundini != npos && ((foundini + strlen(".ini")) == filenameLow.size())) { //found ini file ini_parser::read_ini(fileName, pt); } else { throw ResDataObjectExption("open file failed. file extention is not clear"); return false; } //got pt clear(); return PrintBoostPtObject(pt, 0); } catch (...) { throw ResDataObjectExption("open file failed"); return false; } return true; } bool ResDataObject::loadFile( const char *pfileName ) { if(pfileName == 0) { throw ResDataObjectExption("open file failed"); return false; } ptree pt; std::string fileName = (pfileName); if(fileName.size() == 0) { throw ResDataObjectExption("file name is empty"); return false; } try { std::string filenameLow = fileName; std::transform(filenameLow.begin(), filenameLow.end(), filenameLow.begin(), [](unsigned char c) { return std::tolower(c); }); static const basic_string ::size_type npos = -1; basic_string ::size_type foundini = filenameLow.rfind(".ini"); basic_string ::size_type foundxml = filenameLow.rfind(".xml"); basic_string ::size_type foundjson = filenameLow.rfind(".json"); if(foundxml != npos && ((foundxml+strlen(".xml")) == filenameLow.size())) { //found xml file //xml_parser::read_xml(fileName,pt,xml_parser::trim_whitespace|xml_parser::no_comments); xml_parser::read_xml(fileName, pt, xml_parser::no_comments); } else if(foundjson != npos && ((foundjson+strlen(".json")) == filenameLow.size())) { //found json file json_parser::read_json(fileName,pt); } else if(foundini != npos && ((foundini+strlen(".ini")) == filenameLow.size())) { //found ini file ini_parser::read_ini(fileName,pt); } else { throw ResDataObjectExption("open file failed. file extention is not clear"); return false; } //got pt clear(); return ParsePtToDataObject(*this,pt); } catch (...) { throw ResDataObjectExption("open file failed"); return false; } return true; } bool ResDataObject::SaveFile( const char *pfileName ) { if(pfileName == 0) { throw ResDataObjectExption("Save file failed"); return false; } std::string fileName = (pfileName); if(fileName.size() == 0) { throw ResDataObjectExption("file name is empty"); return false; } try { ptree pt; if(ParseDataObjectToPt(pt,*this) == false) { throw ResDataObjectExption("ParseDataObjectToPt failed"); return false; } std::string filenameLow = fileName; std::transform(filenameLow.begin(), filenameLow.end(), filenameLow.begin(), [](unsigned char c) { return std::tolower(c); }); static const basic_string ::size_type npos = -1; basic_string ::size_type foundini = filenameLow.rfind(".ini"); basic_string ::size_type foundxml = filenameLow.rfind(".xml"); basic_string ::size_type foundjson = filenameLow.rfind(".json"); if(foundxml != npos && ((foundxml+strlen(".xml")) == filenameLow.size())) { //found xml file { //xml_parser::xml_writer_settings settings(' ', 4);//Don't use TAB auto settings = boost::property_tree::xml_writer_make_settings(' ', 4); xml_parser::write_xml(fileName,pt,std::locale(),settings); } } else if(foundjson != npos && ((foundjson+strlen(".json")) == filenameLow.size())) { //found json file json_parser::write_json(fileName,pt); } else if(foundini != npos && ((foundini+strlen(".ini")) == filenameLow.size())) { //found ini file ini_parser::write_ini(fileName,pt); } else { throw ResDataObjectExption("save file failed"); return false; } } catch (...) { throw ResDataObjectExption("save file failed"); return false; } return true; } void ResDataObject::MakeKeyLower() { std::string key; for (size_t i = 0; i < size(); i++) { key = GetKey(i); std::transform(key.begin(), key.end(), key.begin(), [](unsigned char c) { return std::tolower(c); }); SetKey(i, key.c_str()); if ((*this)[i].IsObject()) { (*this)[i].MakeKeyLower(); } } } ResDataObject& ResDataObject::operator = (const char* pVal) { clear(); if (!pVal || reinterpret_cast(pVal) < 0x1000) { // 0x1000是常见的用户态有效内存起始阈值 *m_value = ""; // 用空字符串替代无效指针 } else { *m_value = pVal; // 仅在指针有效时赋值 } return (*this); }; #pragma warning( push ) #pragma warning( disable : 4018 ) //get ResDataObject &ResDataObject::operator [](size_t idx) { if(size() <= idx) { throw ResDataObjectExption("overflow of Idx Of []"); } ResDataObject_Pair& pair = (*m_vec)[idx]; return *pair.second; } ResDataObject &ResDataObject::operator [](int idx) { if(idx < 0) { throw ResDataObjectExption("using minus idx to operate []"); } size_t idx_local = (size_t)idx; return (*this)[idx_local]; } ResDataObject &ResDataObject::operator [](const char *pKey) { if (!pKey) { throw ResDataObjectExption("operator[] param is NULL"); } //keyname = CCommonFun::MAKELOWER(keyname); const std::string keyname(pKey); for (auto& pair : *m_vec) { if (keyname == *pair.first) { return *pair.second; } } // 添加新元素而不是返回静态对象 m_vec->emplace_back(); auto& newPair = m_vec->back(); *newPair.first = keyname; return *newPair.second; }; const char* ResDataObject::GetKey(size_t idx) { if (m_vec && (m_vec->size() <= idx)) { throw ResDataObjectExption("overflow of Idx Of []"); } return (*m_vec)[idx].first->c_str(); } const char* ResDataObject::GetKey(int idx) { if(idx < 0) { throw ResDataObjectExption("try to get key with minus idx"); } size_t idx_local = (size_t)idx; return(*m_vec)[idx_local].first->c_str(); } bool ResDataObject::SetKey(size_t idx,const char *pKey) { if(m_vec && (*m_vec).size() <= idx) { throw ResDataObjectExption("overflow of Idx Of []"); return false; } (*m_vec)[idx].first = std::make_unique(pKey); return true; } ResDataObject::operator bool() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } bool ret1 = 0; std::stringstream strm; strm << (*m_value); strm >> ret1; return ret1; }; ResDataObject::operator char() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } char ret1 = 0; if (StrToIntegerT((*m_value).c_str(), &ret1)) { return ret1; } throw ResDataObjectExption("try to convert a none char"); return ret1; }; ResDataObject::operator unsigned char() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } unsigned char ret1 = 0; if (StrToIntegerT((*m_value).c_str(), &ret1)) { return ret1; } throw ResDataObjectExption("try to convert a none uchar"); return ret1; }; ResDataObject::operator short() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } short ret1 = 0; if (StrToIntegerT((*m_value).c_str(), &ret1)) { return ret1; } throw ResDataObjectExption("try to convert a none short"); return ret1; } ResDataObject::operator unsigned short() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } unsigned short ret1 = 0; if (StrToIntegerT((*m_value).c_str(), &ret1)) { return ret1; } throw ResDataObjectExption("try to convert a none ushort"); return ret1; } ResDataObject::operator int() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } int ret1 = 0; if (StrToIntegerT((*m_value).c_str(), &ret1)) { return ret1; } throw ResDataObjectExption("try to convert a none int"); return ret1; } ResDataObject::operator unsigned int() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } unsigned int ret1 = 0; if (StrToIntegerT((*m_value).c_str(), &ret1)) { return ret1; } throw ResDataObjectExption("try to convert a none uint"); return ret1; } ResDataObject::operator long() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } long ret1 = 0; if (StrToIntegerT((*m_value).c_str(), &ret1)) { return ret1; } throw ResDataObjectExption("try to convert a none long"); return ret1; } ResDataObject::operator unsigned long() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } unsigned long ret1 = 0; if (StrToIntegerT((*m_value).c_str(), &ret1)) { return ret1; } throw ResDataObjectExption("try to convert a none ulong"); return ret1; } ResDataObject::operator long long() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } long long ret1 = 0; if (StrToIntegerT((*m_value).c_str(), &ret1)) { return ret1; } throw ResDataObjectExption("try to convert a none longlong"); return ret1; } ResDataObject::operator unsigned long long() { if(IsObject()) { throw ResDataObjectExption("try to convert a object"); } unsigned long long ret1 = 0; if (StrToIntegerT((*m_value).c_str(), &ret1)) { return ret1; } throw ResDataObjectExption("try to convert a none ulonglong"); return ret1; } ResDataObject::operator float() { if (IsObject()) { throw ResDataObjectExption("try to convert a object"); } return (float)((double)(*this)); } ResDataObject::operator double() { if (IsObject()) { throw ResDataObjectExption("try to convert a object"); } try { return std::stod(*m_value); } catch (...) { throw ResDataObjectExption("Invalid double conversion"); return 0.0; } } ResDataObject::operator const char*() { if (!m_value) { std::cerr << "[ResDataObject] operator const char*: m_value is null" << std::endl; return ""; // 返回空字符串避免崩溃 } return (*m_value).c_str(); }; size_t ResDataObject::GetKeyCount(const char *pKey) { size_t Idx = 0; std::string keyname = (pKey); //keyname = CCommonFun::MAKELOWER(keyname); vector::iterator iter1 = m_vec->begin(); while(iter1 != m_vec->end()) { if(*(iter1->first) == keyname) { ++Idx; } iter1++; } return Idx; } int ResDataObject::GetFirstOf(const char *pKey) { if(pKey == NULL) { return -1; } int Idx = 0; std::string keyname = (pKey); //keyname = CCommonFun::MAKELOWER(keyname); vector::iterator iter1 = m_vec->begin(); while(iter1 != m_vec->end()) { if(*(iter1->first) == keyname) { return Idx; } iter1++; ++Idx; } return -1; } int ResDataObject::GetNextOf(const char *pKey,int PrevIdx) { if(pKey == NULL) { return -1; } int Idx = 0; std::string keyname = (pKey); //keyname = CCommonFun::MAKELOWER(keyname); vector::iterator iter1 = m_vec->begin(); while(iter1 != m_vec->end()) { if(*(iter1->first) == keyname) { if(Idx > PrevIdx) { return Idx; } } iter1++; ++Idx; } return -1; } #pragma warning( pop ) //erase bool ResDataObject::eraseAllOf(const char *pKey) { if (pKey == NULL) { throw ResDataObjectExption("eraseAllOf: pKey cannot be NULL"); return false; } std::string keyname = (pKey); //keyname = CCommonFun::MAKELOWER(keyname); vector::iterator iter1 = m_vec->begin(); while(iter1 != m_vec->end()) { if(*(iter1->first) == (keyname)) { iter1 = m_vec->erase(iter1); continue; } iter1++; } return true; }; bool ResDataObject::eraseOneOf(const char *pKey,size_t idx) { if(pKey == NULL) { throw ResDataObjectExption("eraseOneOf failed"); return false; } size_t curIdx = 0; std::string keyname = (pKey); //keyname = CCommonFun::MAKELOWER(keyname); vector::iterator iter1 = m_vec->begin(); for(;iter1 != m_vec->end();iter1++) { if(*(iter1->first) == (keyname)) { if(curIdx == idx) { iter1 = m_vec->erase(iter1); return true; } else { ++curIdx; } } } return false; }; ResDataObject& ResDataObject::operator += (const ResDataObject &tValue) { if (this != &tValue) { const auto& src_vec = *tValue.m_vec; for (const auto& src_pair : src_vec) { ResDataObject_Pair new_pair; *new_pair.first = *src_pair.first; *new_pair.second = *src_pair.second; m_vec->push_back(new_pair); } } return *this; } ResDataObject& ResDataObject::operator=(const ResDataObject& tValue) { if (this != &tValue) { *m_encode = *tValue.m_encode; *m_value = *tValue.m_value; m_vec->clear(); m_vec->reserve(tValue.m_vec->size()); for (const auto& src_pair : *tValue.m_vec) { ResDataObject_Pair new_pair; // 深拷贝first if (src_pair.first) { *new_pair.first = *src_pair.first; } // 深拷贝second if (src_pair.second) { *new_pair.second = *src_pair.second; } m_vec->push_back(std::move(new_pair)); } } return *this; } ResDataObject& ResDataObject::operator = (const bool tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const char tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const unsigned char tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const short tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const unsigned short tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const int tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const unsigned int tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const long tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const unsigned long tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const long long tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const unsigned long long tValue) { std::stringstream strm; strm << tValue; (*this) = strm.str().c_str(); return (*this); } ResDataObject& ResDataObject::operator = (const float tValue) { double DtValue = tValue; (*this) = DtValue; return (*this); } ResDataObject& ResDataObject::operator = (const double tValue) { //unsigned long long temp,*pF ; std::stringstream strm; //strm.precision(numeric_limits::digits10); //新方案(丢精度) char szStr[64]; snprintf(szStr, sizeof(szStr), "%.17g", tValue); strm << szStr; (*this) = strm.str().c_str(); return (*this); //旧方案(保持精度) //assert(sizeof(double) == sizeof(unsigned long long)); //pF = (unsigned long long*)&tValue; //temp = (*pF); //strm << temp; //(*this) = strm.str().c_str(); //return (*this); } bool ResDataObject::add(const char* pKey,bool tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,char tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,unsigned char tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,short tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,unsigned short tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,int tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,unsigned int tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,long tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,unsigned long tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,long long tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,unsigned long long tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,float tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,double tValue) { ResDataObject obj; obj = tValue; return add(pKey,obj); } bool ResDataObject::add(const char* pKey,const char* pValue) { ResDataObject obj; if (!pValue || reinterpret_cast(pValue) < 0x1000) { obj = ""; // 无效值用空字符串替代 } else { obj = pValue; } return add(pKey,obj); } bool ResDataObject::add(const char* pKey,ResDataObject &dataobj) { if (!m_vec) { std::cerr << "Error: m_vec is null in ResDataObject::add" << std::endl; m_vec = std::make_unique>(); } if (!pKey) pKey = ""; // 处理空指针 try { m_vec->emplace_back(); auto& new_pair = m_vec->back(); *new_pair.first = pKey; *new_pair.second = dataobj; return true; } catch (...) { std::cerr << "[add] vector@" << m_vec.get() << " is invalid (memory corrupted)" << std::endl; return false; } }; bool ResDataObject::update(const char* pKey,bool tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,char tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,unsigned char tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,short tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,unsigned short tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,int tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,unsigned int tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,long tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,unsigned long tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,long long tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,unsigned long long tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,float tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,double tValue) { eraseAllOf(pKey); return add(pKey,tValue); } bool ResDataObject::update(const char* pKey,const char* pValue) { eraseAllOf(pKey); return add(pKey,pValue); } bool ResDataObject::update(const char* pKey,ResDataObject &dataobj) { eraseAllOf(pKey); return add(pKey,dataobj); } bool ResDataObject::operator == (const char* pVal) { std::string exVal = pVal; return ((*m_value) == exVal); } bool ResDataObject::operator == (const ResDataObject &Obj) { //compare val if ((*m_value) != (*(Obj.m_value))) { return false; } //compare count if (m_vec->size() != Obj.m_vec->size()) { return false; } //compare vec for (size_t i = 0; i < m_vec->size(); i++) { if ((*((*m_vec)[i]).first) != (*((*Obj.m_vec)[i]).first)) { return false; } if ((*((*m_vec)[i]).second) == (*((*Obj.m_vec)[i]).second)) { continue; } return false; } return true; } RESDATAOBJECT_C_API bool TryGetValue(ResDataObject &obj, const char *pKey, ResDataObject &res) { bool ret = true; try { res.clear(); if (obj.GetFirstOf(pKey) >= 0) { res = obj[pKey]; } else { ret = false; } } catch (...) { res.clear(); ret = false; } return ret; } //---------------------------------------------------------------- ExJsonDataObject::ExJsonDataObject() : m_pKey(std::make_unique()), m_ValString(std::make_unique()), m_pTargetObject(std::make_unique()) { } ExJsonDataObject::ExJsonDataObject(const ExJsonDataObject& tValue) : m_pKey(std::make_unique(*tValue.m_pKey)), m_ValString(std::make_unique(*tValue.m_ValString)), m_pTargetObject(std::make_unique(*tValue.m_pTargetObject)) { } //base void ExJsonDataObject::SetKey(const char *pKey) { *m_pKey = pKey ? pKey : ""; } const char *ExJsonDataObject::GetKey() { return m_pKey->c_str(); } ResDataObject &ExJsonDataObject::GetResDataObject() { return (*m_pTargetObject); } bool ExJsonDataObject::SetResDataObject(ResDataObject &obj) { bool ret = true; try { //check it first for (size_t i = 0; i < m_pTargetObject->size(); i++) { const char* pKey = m_pTargetObject->GetKey(i); if (pKey) { int IdxObj = obj.GetFirstOf(pKey); if (IdxObj < 0) { ret = false; break; } } else { ret = false; break; } } //copy it if (ret) { (*m_pTargetObject) = obj; //for (size_t i = 0; i < m_pTargetObject->size(); i++) //{ // (*m_pTargetObject)[i] = obj[obj.GetFirstOf(m_pTargetObject->GetKey(i))]; //} } } catch (...) { ret = false; } return ret; } ResDataObject &ExJsonDataObject::operator [](const char *pKey) { try { return (*m_pTargetObject)[pKey]; } catch (...) { assert(0);//make sure never gonna happen } return (*m_pTargetObject); } ExJsonDataObject &ExJsonDataObject::operator = (const ExJsonDataObject &tValue) { if (this != &tValue) { (*m_pKey) = *(tValue.m_pKey); (*m_ValString) = *(tValue.m_ValString); (*m_pTargetObject) = *(tValue.m_pTargetObject); } return (*this); }