123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815 |
- //#include "StdAfx.h"
- #define BOOST_SPIRIT_THREADSAFE
- #include "ResDataObject.h"
- #include <filesystem>
- #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(other.first ? std::make_unique<std::string>(*other.first)
- : std::make_unique<std::string>()),
- second(other.second ? std::make_unique<ResDataObject>(*other.second)
- : std::make_unique<ResDataObject>())
- {
- }
- ResDataObject_Pair& ResDataObject_Pair::operator=(const ResDataObject_Pair& other)
- {
- if (this != &other) {
- *first = *other.first;
- *second = *other.second;
- }
- 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(void)
- {
- }
- //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) {
- throw ResDataObjectExption("Null filename pointer");
- return false;
- }
- namespace fs = std::filesystem;
- const fs::path filePath(pfileName);
- // 验证文件存在且可读
- if (!fs::exists(filePath)) {
- throw ResDataObjectExption(("File does not exist: " + filePath.string()).c_str());
- }
- if (!fs::is_regular_file(filePath)) {
- throw ResDataObjectExption(("Not a regular file: " + filePath.string()).c_str());
- }
- const uintmax_t fileSize = fs::file_size(filePath);
- if (fileSize == 0) {
- throw ResDataObjectExption(("Empty file: " + filePath.string()).c_str());
- }
- const uintmax_t MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
- if (fileSize > MAX_FILE_SIZE) {
- throw ResDataObjectExption(("File too large: " + filePath.string()).c_str());
- }
- std::unique_ptr<ptree> ptPtr = std::make_unique<ptree>();
- try
- {
- std::string fileName(pfileName);
- std::string filenameLow = fileName;
- std::transform(filenameLow.begin(), filenameLow.end(), filenameLow.begin(),
- [](unsigned char c) { return std::tolower(c); });
- static const std::string::size_type npos = -1;
- std::string::size_type foundxml = filenameLow.rfind(".xml");
- std::string::size_type foundjson = filenameLow.rfind(".json");
- std::string::size_type foundini = filenameLow.rfind(".ini");
-
- auto throwError = [](const std::string& msg) {
- throw ResDataObjectExption(msg.c_str());
- };
- if (foundxml != npos && ((foundxml + 4) == filenameLow.size()))
- {
- // XML 文件处理 - 修正了标志问题
- const int flags =
- boost::property_tree::xml_parser::no_comments |
- boost::property_tree::xml_parser::trim_whitespace;
- // 使用文件流代替直接路径
- std::ifstream ifs(fileName, std::ios::binary);
- if (!ifs) {
- throwError("Cannot open file: " + fileName);
- }
- // 读取文件内容
- std::vector<char> buffer;
- buffer.reserve(fileSize + 1); // 预分配空间
- buffer.assign(std::istreambuf_iterator<char>(ifs),
- std::istreambuf_iterator<char>());
- buffer.push_back('\0');
- // 使用字符串流解析
- std::istringstream iss(buffer.data());
- boost::property_tree::read_xml(iss, *ptPtr, flags);
- }
- else if(foundjson != npos && ((foundjson+strlen(".json")) == filenameLow.size()))
- {
- // JSON 文件处理
- std::ifstream ifs(fileName, std::ios::binary);
- if (!ifs) {
- throwError("Cannot open file: " + fileName);
- }
- const size_t MAX_DEPTH = 50;
- ptPtr->put("debug.max_depth", MAX_DEPTH);
- try {
- std::string jsonContent(
- (std::istreambuf_iterator<char>(ifs)),
- std::istreambuf_iterator<char>()
- );
- if (jsonContent.empty()) {
- throwError("Empty JSON content: " + fileName);
- }
- std::istringstream jsonStream(jsonContent);
- boost::property_tree::read_json(jsonStream, *ptPtr);
- }
- catch (const boost::property_tree::json_parser_error& e) {
- throwError(std::string("JSON parse error: ") + e.what());
- }
- }
- else if(foundini != npos && ((foundini+strlen(".ini")) == filenameLow.size()))
- {
- // INI 文件处理
- std::ifstream ifs(fileName, std::ios::binary);
- if (!ifs) {
- throwError("Cannot open file: " + fileName);
- }
- try {
- boost::property_tree::ini_parser::read_ini(ifs, *ptPtr);
- }
- catch (const boost::property_tree::ini_parser_error& e) {
- throwError(std::string("INI parse error: ") + e.what());
- }
- }
- else
- {
- throwError("Unsupported file extension: " + filenameLow);
- }
- //got pt
- clear();
- bool result = ParsePtToDataObject(*this, *ptPtr);
- ptPtr.reset();
- return result;
- }
- catch (const boost::property_tree::ptree_error& e) {
- throw ResDataObjectExption(("Property tree error: " + std::string(e.what())).c_str());
- return false;
- }
- catch (const std::exception& e) {
- throw ResDataObjectExption(("Standard error: " + std::string(e.what())).c_str());
- return false;
- }
- catch (...) {
- throw ResDataObjectExption("Unknown error occurred");
- 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 ? *tValue.m_encode : "";
- *m_value = tValue.m_value ? *tValue.m_value : "";
- m_vec->clear();
- if (tValue.m_vec) {
- m_vec->reserve(tValue.m_vec->size());
- for (const auto& src_pair : *tValue.m_vec) {
- ResDataObject_Pair new_pair(src_pair);
- 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);
- }
|