12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784 |
- //#include "StdAfx.h"
- #define BOOST_SPIRIT_THREADSAFE
- #include "ResDataObject.h"
- #include <boost/property_tree/ptree.hpp>
- #include <boost/property_tree/xml_parser.hpp>
- #include <boost/property_tree/json_parser.hpp>
- #include <boost/property_tree/ini_parser.hpp>
- #include <boost/typeof/typeof.hpp>
- #include <boost/exception/all.hpp>
- #include <boost/foreach.hpp>
- #include "CommonFun.h"
- #define CRTDBG_MAP_ALLOC
- #include <stdlib.h>
- #include <fstream>
- //#include <crtdbg.h>
- #include <locale>
- #include <codecvt>
- #include <iostream>
- using namespace boost::property_tree;
- //general data object--------------------------------------
- std::string wc2mb( const wchar_t* wcstr)
- {
- std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
- std::string strVal = conv.to_bytes(wcstr); // 将宽字符字符串转换为UTF-8编码的多字节字符串
- return strVal;
- }
- std::wstring mb2wc(const char* mbstr)
- {
- std::wstring_convert<std::codecvt_utf8<wchar_t>> 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 <class Type> 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<const char*>(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<std::string>(pExp ? pExp : "")) {}
- ResDataObjectExption::ResDataObjectExption(const ResDataObjectExption &tValue) : m_ExpContext(std::make_unique<std::string>(*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<std::string>()),
- second(std::make_unique<ResDataObject>()) {}
- ResDataObject_Pair::ResDataObject_Pair(const ResDataObject_Pair& other)
- : first(std::make_unique<std::string>(*other.first)),
- second(std::make_unique<ResDataObject>(*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<std::string>();
- }
- if (!other.second) {
- other.second = std::make_unique<ResDataObject>();
- }
- }
- return *this;
- }
- ResDataObject::ResDataObject(void) :
- m_encode(std::make_unique<std::string>()),
- m_value(std::make_unique<std::string>()),
- m_vec(std::make_unique<std::vector<ResDataObject_Pair>>()) {}
- ResDataObject::ResDataObject(const ResDataObject& tValue)
- : m_encode(std::make_unique<std::string>(*tValue.m_encode)),
- m_value(std::make_unique<std::string>(*tValue.m_value)),
- m_vec(std::make_unique<std::vector<ResDataObject_Pair>>())
- {
- 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<std::string>();
- tValue.m_value = std::make_unique<std::string>();
- tValue.m_vec = std::make_unique<std::vector<ResDataObject_Pair>>();
- //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<std::vector<ResDataObject_Pair>>();
- }
- 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 <char>::size_type npos = -1;
- basic_string <char>::size_type foundini = filenameLow.rfind(".ini");
- basic_string <char>::size_type foundxml = filenameLow.rfind(".xml");
- basic_string <char>::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 <char>::size_type npos = -1;
- basic_string <char>::size_type foundini = filenameLow.rfind(".ini");
- basic_string <char>::size_type foundxml = filenameLow.rfind(".xml");
- basic_string <char>::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 <char>::size_type npos = -1;
- basic_string <char>::size_type foundini = filenameLow.rfind(".ini");
- basic_string <char>::size_type foundxml = filenameLow.rfind(".xml");
- basic_string <char>::size_type foundjson = filenameLow.rfind(".json");
- if(foundxml != npos && ((foundxml+strlen(".xml")) == filenameLow.size()))
- {
- //found xml file
- {
- //xml_parser::xml_writer_settings<char> settings(' ', 4);//Don't use TAB
- auto settings = boost::property_tree::xml_writer_make_settings<string>(' ', 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<uintptr_t>(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<std::string>(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<ResDataObject_Pair>::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<ResDataObject_Pair>::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<ResDataObject_Pair>::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<ResDataObject_Pair>::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<ResDataObject_Pair>::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<double>::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<uintptr_t>(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<std::vector<ResDataObject_Pair>>();
- }
- 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<std::string>()),
- m_ValString(std::make_unique<std::string>()),
- m_pTargetObject(std::make_unique<ResDataObject>()) {
- }
- ExJsonDataObject::ExJsonDataObject(const ExJsonDataObject& tValue)
- : m_pKey(std::make_unique<std::string>(*tValue.m_pKey)),
- m_ValString(std::make_unique<std::string>(*tValue.m_ValString)),
- m_pTargetObject(std::make_unique<ResDataObject>(*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);
- }
|