1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858 |
- //#include "StdAfx.h"
- #define BOOST_SPIRIT_THREADSAFE
- #include <filesystem>
- #include <stdlib.h>
- #include <fstream>
- #include <locale>
- #include <codecvt>
- #include <iostream>
- #include <boost/bind/bind.hpp>
- #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 "ResDataObject.h"
- #include "CommonFun.h"
- using namespace boost::placeholders;
- #define CRTDBG_MAP_ALLOC
- //#include <crtdbg.h>
- 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) {
- return *this;
- }
- // 安全地处理字符串赋值
- if (m_encode) {
- *m_encode = tValue.m_encode ? *tValue.m_encode : "";
- }
- else if (tValue.m_encode) {
- m_encode = std::make_unique<std::string>(*tValue.m_encode);
- }
- if (m_value) {
- *m_value = tValue.m_value ? *tValue.m_value : "";
- }
- else if (tValue.m_value) {
- m_value = std::make_unique<std::string>(*tValue.m_value);
- }
- // 处理向量数据
- if (!tValue.m_vec) {
- m_vec.reset();
- }
- else {
- if (!m_vec) {
- m_vec = std::make_unique<std::vector<ResDataObject_Pair>>();
- }
- m_vec->clear();
- m_vec->reserve(tValue.m_vec->size());
- for (const auto& src_pair : *tValue.m_vec) {
- m_vec->emplace_back(src_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>>();
- }
- const char* safeKey = pKey ? pKey : "";
- try {
- m_vec->emplace_back();
- auto& new_pair = m_vec->back();
- if (new_pair.first) {
- *new_pair.first = safeKey;
- }
- else {
- new_pair.first = std::make_unique<std::string>(safeKey);
- }
- if (new_pair.second) {
- *new_pair.second = dataobj;
- }
- else {
- new_pair.second = std::make_unique<ResDataObject>(dataobj);
- }
- return true;
- }
- catch (const std::exception& e) {
- std::cerr << "Error in ResDataObject::add: " << e.what() << std::endl;
- return false;
- }
- catch (...) {
- std::cerr << "Unknown error in ResDataObject::add" << 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);
- }
|