From bf07a8015abb40b549a37222f318fb33b1c8dc00 Mon Sep 17 00:00:00 2001 From: ruanshudong Date: Sat, 30 Nov 2019 20:01:04 +0800 Subject: [PATCH] support simple json tars2json --- servant/tup/TarsJson.h | 768 ++++++++++++++++++++++++++++++++++ tools/tars2cpp/main.cpp | 37 +- tools/tars2cpp/tars2cpp.cpp | 794 ++++++++++++++++++++++-------------- tools/tars2cpp/tars2cpp.h | 45 +- util/include/util/tc_json.h | 259 ++++++++++++ util/src/tc_json.cpp | 626 ++++++++++++++++++++++++++++ 6 files changed, 2195 insertions(+), 334 deletions(-) create mode 100644 servant/tup/TarsJson.h create mode 100644 util/include/util/tc_json.h create mode 100644 util/src/tc_json.cpp diff --git a/servant/tup/TarsJson.h b/servant/tup/TarsJson.h new file mode 100644 index 0000000..9304fae --- /dev/null +++ b/servant/tup/TarsJson.h @@ -0,0 +1,768 @@ +#ifndef __TARS_JSON_H__ +#define __TARS_JSON_H__ + +#include +#include +#include +#include +#include +#include +#include + +#include "util/tc_json.h" +#include "util/tc_common.h" + +namespace tars +{ +class JsonInput +{ +public: + static void readJson(Bool& b, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeBoolean) + { + b = JsonValueBooleanPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'Bool' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(Char& c, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeNum) + { + c = (char)JsonValueNumPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'Char' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(UInt8& n, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeNum) + { + n = (UInt8)JsonValueNumPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'Uint8' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(Short& n, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeNum) + { + n = (Short)JsonValueNumPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'Short' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(UInt16& n, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeNum) + { + n = (UInt16)JsonValueNumPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'Uint16' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(Int32& n, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeNum) + { + n = (Int32)JsonValueNumPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'Int32' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(UInt32& n, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeNum) + { + n = (UInt32)JsonValueNumPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'UInt32' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(Int64& n, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeNum) + { + n = (Int64)JsonValueNumPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'Int64' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(Float& n, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeNum) + { + n = (Float)JsonValueNumPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'Float' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(Double& n, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeNum) + { + n = JsonValueNumPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'Double' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(std::string& s, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeString) + { + s = JsonValueStringPtr::dynamicCast(p)->value; + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'string' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + static void readJson(char *buf, const UInt32 bufLen, UInt32 & readLen, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeString) + { + JsonValueStringPtr pString=JsonValueStringPtr::dynamicCast(p); + if((UInt32)pString->value.size()>bufLen) + { + char s[128]; + snprintf(s, sizeof(s), "invalid char * size, size: %u", (UInt32)pString->value.size()); + throw TC_Json_Exception(s); + } + memcpy(buf,pString->value.c_str(),pString->value.size()); + readLen = (UInt32)pString->value.size(); + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'char *' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=iter->first; + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=TC_Common::strto(iter->first); + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=TC_Common::strto(iter->first); + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=TC_Common::strto(iter->first); + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=TC_Common::strto(iter->first); + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=TC_Common::strto(iter->first); + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=TC_Common::strto(iter->first); + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=TC_Common::strto(iter->first); + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=TC_Common::strto(iter->first); + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=TC_Common::strto(iter->first); + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + auto iter=pObj->value.begin(); + for(;iter!=pObj->value.end();++iter) + { + std::pair pr; + pr.first=TC_Common::strto(iter->first); + readJson(pr.second,iter->second); + m.insert(pr); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + template + static void readJson(std::map& m, const JsonValuePtr & p, bool isRequire = true) + { + char s[128]; + snprintf(s, sizeof(s), "map key is not Basic type. map key is only string|bool|num"); + throw TC_Json_Exception(s); + } + + template + static void readJson(std::vector& v, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeArray) + { + JsonValueArrayPtr pArray=JsonValueArrayPtr::dynamicCast(p); + v.resize(pArray->value.size()); + for(size_t i=0;ivalue.size();++i) + { + readJson(v[i],pArray->value[i]); + } + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'vector' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + /// 读取结构数组 + template + static void readJson(T* v, const UInt32 len, UInt32 & readLen, const JsonValuePtr & p, bool isRequire = true) + { + if(NULL != p.get() && p->getType() == eJsonTypeArray) + { + JsonValueArrayPtr pArray=JsonValueArrayPtr::dynamicCast(p); + if(pArray->value.size()>len) + { + char s[128]; + snprintf(s, sizeof(s), "read 'T *' invalid size, size: %u", (uint32_t)pArray->value.size()); + throw TC_Json_Exception(s); + } + for(size_t i=0;ivalue.size();++i) + { + readJson(v[i],pArray->value[i]); + } + readLen=pArray->value.size(); + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'T *' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } + + template + static void readJson(T& v, const JsonValuePtr & p, bool isRequire = true, typename detail::disable_if, void ***>::type dummy = 0) + { + Int32 n = 0; + readJson(n, p, isRequire); + v = (T) n; + } + + /// 读取结构 + template + static void readJson(T& v, const JsonValuePtr & p, bool isRequire = true, typename detail::enable_if, void ***>::type dummy = 0) + { + if(NULL != p.get() && p->getType() == eJsonTypeObj) + { + JsonValueObjPtr pObj=JsonValueObjPtr::dynamicCast(p); + v.readFromJson(pObj); + } + else if (isRequire) + { + char s[128]; + snprintf(s, sizeof(s), "read 'Char' type mismatch, get type: %d.", p->getType()); + throw TC_Json_Exception(s); + } + } +}; + +class JsonOutput +{ +public: + static JsonValueBooleanPtr writeJson(Bool b) + { + JsonValueBooleanPtr p = new JsonValueBoolean(); + p->value=b; + return p; + } + + static JsonValueNumPtr writeJson(Char n) + { + return (new JsonValueNum(n,true)); + } + + static JsonValueNumPtr writeJson(UInt8 n) + { + return (new JsonValueNum(n,true)); + } + + static JsonValueNumPtr writeJson(Short n) + { + return (new JsonValueNum(n,true)); + } + + static JsonValueNumPtr writeJson(UInt16 n) + { + return (new JsonValueNum(n,true)); + } + + static JsonValueNumPtr writeJson(Int32 n) + { + return (new JsonValueNum(n,true)); + } + + static JsonValueNumPtr writeJson(UInt32 n) + { + return (new JsonValueNum(n,true)); + } + + static JsonValueNumPtr writeJson(Int64 n) + { + return (new JsonValueNum((double)n,true)); + } + + static JsonValueNumPtr writeJson(Float n) + { + return (new JsonValueNum(n)); + } + + static JsonValueNumPtr writeJson(Double n) + { + return (new JsonValueNum(n)); + } + + static JsonValueStringPtr writeJson(const std::string& s) + { + return (new JsonValueString(s)); + } + + static JsonValueStringPtr writeJson(const char *buf, const UInt32 len) + { + return (new JsonValueString(string(buf,len))); + } + + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[i->first]=writeJson(i->second); + } + return pObj; + } + + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[TC_Common::tostr(i->first)]=writeJson(i->second); + } + return pObj; + } + + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[TC_Common::tostr((Int32)i->first)]=writeJson(i->second); + } + return pObj; + } + + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[TC_Common::tostr(i->first)]=writeJson(i->second); + } + return pObj; + } + + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[TC_Common::tostr(i->first)]=writeJson(i->second); + } + return pObj; + } + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[TC_Common::tostr(i->first)]=writeJson(i->second); + } + return pObj; + } + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[TC_Common::tostr(i->first)]=writeJson(i->second); + } + return pObj; + } + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[TC_Common::tostr(i->first)]=writeJson(i->second); + } + return pObj; + } + + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[TC_Common::tostr(i->first)]=writeJson(i->second); + } + return pObj; + } + + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[TC_Common::tostr(i->first)]=writeJson(i->second); + } + return pObj; + } + + template + static JsonValueObjPtr writeJson(const std::map& m) + { + JsonValueObjPtr pObj=new JsonValueObj(); + typedef typename std::map::const_iterator IT; + for (IT i = m.begin(); i != m.end(); ++i) + { + pObj->value[TC_Common::tostr(i->first)]=writeJson(i->second); + } + return pObj; + } + + template + static JsonValueObjPtr writeJson(const std::map& m) + { + char s[128]; + snprintf(s, sizeof(s), "map key is not Basic type. map key is only string|bool|num"); + throw TC_Json_Exception(s); + } + + template + static JsonValueArrayPtr writeJson(const std::vector& v) + { + JsonValueArrayPtr pArray=new JsonValueArray(); + typedef typename std::vector::const_iterator IT; + for (IT i = v.begin(); i != v.end(); ++i) + pArray->value.push_back(writeJson(*i)); + return pArray; + } + + template + static JsonValueArrayPtr writeJson(const T *v, const UInt32 len) + { + JsonValueArrayPtr pArray=new JsonValueArray(); + for (size_t i = 0; i < len; ++i) + { + pArray->value.push_back(writeJson(v[i])); + } + return pArray; + } + + template + static JsonValueNumPtr writeJson(const T& v, typename detail::disable_if, void ***>::type dummy = 0) + { + return writeJson((Int32) v); + } + + template + static JsonValueObjPtr writeJson(const T& v, typename detail::enable_if, void ***>::type dummy = 0) + { + return v.writeToJson(); + } +}; +//////////////////////////////////////////////////////////////////////////////////////////////////// +} + + +#endif diff --git a/tools/tars2cpp/main.cpp b/tools/tars2cpp/main.cpp index 09e5aaa..7ddb2c7 100644 --- a/tools/tars2cpp/main.cpp +++ b/tools/tars2cpp/main.cpp @@ -23,13 +23,14 @@ void usage() { cout << "Usage : tars2cpp [OPTION] tarsfile" << endl; - cout << " --coder=Demo::interface1;Demo::interface2 create interface encode and decode api" << endl; + // cout << " --coder=Demo::interface1;Demo::interface2 create interface encode and decode api" << endl; cout << " --dir=DIRECTORY generate source file to DIRECTORY(生成文件到目录DIRECTORY,默认为当前目录)" << endl; cout << " --check-default= 如果optional字段值为默认值不打包(默认打包)" << endl; + cout << " --unjson 不生成json编解码" << endl; cout << " --os 只生成tars文件中结构体编解码的程序段" << endl; cout << " --include=\"dir1;dir2;dir3\" 设置tars文件搜索路径" << endl; cout << " --unknown 生成处理tars数据流中的unkown field的代码" << endl; - cout << " --tarsMaster 生成获取主调信息的选项" << endl; + cout << " --tarsMaster 生成获取主调信息的选项" << endl; cout << " --currentPriority use current path first." << endl; cout << " tars2cpp support type: bool byte short int long float double vector map" << endl; exit(0); @@ -75,17 +76,17 @@ int main(int argc, char* argv[]) usage(); } - bool bCoder = option.hasParam("coder"); - vector vCoder; - if(bCoder) - { - vCoder = tars::TC_Common::sepstr(option.getValue("coder"), ";", false); - if(vCoder.size() == 0) - { - usage(); - return 0; - } - } + // bool bCoder = option.hasParam("coder"); + // vector vCoder; + // if(bCoder) + // { + // vCoder = tars::TC_Common::sepstr(option.getValue("coder"), ";", false); + // if(vCoder.size() == 0) + // { + // usage(); + // return 0; + // } + // } Tars2Cpp t2c; @@ -102,6 +103,14 @@ int main(int argc, char* argv[]) t2c.setOnlyStruct(option.hasParam("os")); + //默认支持json + t2c.setJsonSupport(true); + + if (option.hasParam("unjson")) + { + t2c.setJsonSupport(false); + } + t2c.setTarsMaster(option.hasParam("tarsMaster")); try @@ -119,7 +128,7 @@ int main(int argc, char* argv[]) { g_parse->parse(vTars[i]); - t2c.createFile(vTars[i], vCoder); + t2c.createFile(vTars[i]);//, vCoder); } } catch(exception& e) diff --git a/tools/tars2cpp/tars2cpp.cpp b/tools/tars2cpp/tars2cpp.cpp index 326fce1..a8cfc4a 100644 --- a/tools/tars2cpp/tars2cpp.cpp +++ b/tools/tars2cpp/tars2cpp.cpp @@ -29,6 +29,7 @@ Tars2Cpp::Tars2Cpp() : _checkDefault(false) , _onlyStruct(false) +, _bJsonSupport(true) , _namespace("tars") , _unknownField(false) , _tarsMaster(false) @@ -36,6 +37,105 @@ Tars2Cpp::Tars2Cpp() } +string Tars2Cpp::writeToJson(const TypeIdPtr& pPtr) const +{ + ostringstream s; + if (EnumPtr::dynamicCast(pPtr->getTypePtr())) + { + s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace + "::JsonOutput::writeJson((" + _namespace + "::Int32)" + << pPtr->getId() << ");" << endl; + } + else if (pPtr->getTypePtr()->isArray()) + { + s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace + "::JsonOutput::writeJson((const " + << tostr(pPtr->getTypePtr()) << " *)" << pPtr->getId() << "Len" << ");" << endl; + } + else if (pPtr->getTypePtr()->isPointer()) + { + s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace + "::JsonOutput::writeJson((const " + << tostr(pPtr->getTypePtr()) << " )" << pPtr->getId() << "Len" << ");" << endl; + } + else + { + MapPtr mPtr = MapPtr::dynamicCast(pPtr->getTypePtr()); + VectorPtr vPtr = VectorPtr::dynamicCast(pPtr->getTypePtr()); + + // 对于json, 不检测默认值 + if (true || !_checkDefault || pPtr->isRequire() || (!pPtr->hasDefault() && !mPtr && !vPtr)) + { + s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace + "::JsonOutput::writeJson(" + << pPtr->getId() << ");" << endl; + } + else + { + string sDefault = pPtr->def(); + + BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr()); + if (bPtr && bPtr->kind() == Builtin::KindString) + { + sDefault = "\"" + tars::TC_Common::replace(pPtr->def(), "\"", "\\\"") + "\""; + } + + if (mPtr || vPtr) + { + s << TAB << "if (" << pPtr->getId() << ".size() > 0)" << endl; + } + else if (bPtr && (bPtr->kind() == Builtin::KindFloat || bPtr->kind() == Builtin::KindDouble)) + { + s << TAB << "if (!tars::TC_Common::equal(" << pPtr->getId() << "," << sDefault << "))" << endl; + } + else + { + s << TAB << "if (" << pPtr->getId() << " != " << sDefault << ")" << endl; + } + + s << TAB << "{" << endl; + INC_TAB; + s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace + "::JsonOutput::writeJson(" + << pPtr->getId() << ");" << endl; + DEL_TAB; + s << TAB << "}" << endl; + } + } + + return s.str(); +} + +string Tars2Cpp::readFromJson(const TypeIdPtr& pPtr, bool bIsRequire) const +{ + ostringstream s; + // if (EnumPtr::dynamicCast(pPtr->getTypePtr())) + // { + // s << TAB << _namespace + "::JsonInput::readJson((" + _namespace + "::Int32&)" << pPtr->getId() << ",pObj->value[\"" << pPtr->getId() << "\"]"; + // } + // else + + if (pPtr->getTypePtr()->isArray()) + { + s << TAB << _namespace + "::JsonInput::readJson(" << pPtr->getId() << "Len" << ",pObj->value[\"" << pPtr->getId() << "\"]" << getSuffix(pPtr); + } + else if (pPtr->getTypePtr()->isPointer()) + { +#if 0 + s << TAB << pPtr->getId() <<" = ("<getTypePtr())<<")_is.cur();"<getId()<<", _is.left(), "<< pPtr->getId() << "Len"; +#endif + s << TAB << "not support"; + } + else + { + s << TAB << _namespace + "::JsonInput::readJson(" << pPtr->getId() << ",pObj->value[\"" << pPtr->getId() << "\"]"; + } + s << ", " << ((pPtr->isRequire() && bIsRequire) ? "true" : "false") << ");" << endl; + +#if 0 + if(pPtr->getTypePtr()->isPointer()) + s << TAB <<"_is.mapBufferSkip("<getId() << "Len);"<getType() != tars::eJsonTypeObj)" << endl; + s << TAB << "{" << endl; + INC_TAB; + s << TAB << "char s[128];" << endl; + s << TAB << "snprintf(s, sizeof(s), \"read 'struct' type mismatch, get type: %d.\", (p.get() ? p->getType() : 0));" << endl; + s << TAB << "throw tars::TC_Json_Exception(s);" << endl; + DEL_TAB; + s << TAB << "}" << endl; + s << TAB << "tars::JsonValueObjPtr pObj=tars::JsonValueObjPtr::dynamicCast(p);" << endl; + for (size_t j = 0; j < member.size(); j++) + { + s << readFromJson(member[j]); + } + DEL_TAB; + s << TAB << "}" << endl; + + s << TAB << "void readFromJsonString(const string & str)" << endl; + s << TAB << "{" << endl; + INC_TAB; + s << TAB << "readFromJson(tars::TC_Json::getValue(str));" << endl; + DEL_TAB; + s << TAB << "}" << endl; + } + s << TAB << "ostream& display(ostream& _os, int _level=0) const" << endl; s << TAB << "{" << endl; INC_TAB; @@ -624,7 +773,7 @@ string Tars2Cpp::generateH(const StructPtr& pPtr, const string& namespaceId) con } if (_unknownField) { - s << TAB << "std::string sUnknownField; //¹¤¾ß´ø--unknown²ÎÊý×Ô¶¯Éú³É×Ö¶Î,´æ·Åδ֪tagÊý¾Ý." << endl; + s << TAB << "std::string sUnknownField;" << endl; } DEL_TAB; s << TAB << "};" << endl; @@ -661,6 +810,32 @@ string Tars2Cpp::generateH(const StructPtr& pPtr, const string& namespaceId) con DEL_TAB; s << TAB << "}" << endl; + + //定义 << >> + if (_bJsonSupport) + { + //重载 << + s << TAB << "inline ostream& operator<<(ostream & os,const " << pPtr->getId() << "&r)" << endl; + s << TAB << "{" << endl; + INC_TAB; + s << TAB << "os << r.writeToJsonString();" << endl; + s << TAB << "return os;" << endl; + DEL_TAB; + s << TAB << "}" << endl; + + //重载 >> + s << TAB << "inline istream& operator>>(istream& is," << pPtr->getId() << "&l)" << endl; + s << TAB << "{" << endl; + INC_TAB; + s << TAB << "std::istreambuf_iterator eos;" << endl; + s << TAB << "std::string s(std::istreambuf_iterator(is), eos);" << endl; + s << TAB << "l.readFromJsonString(s);" << endl; + s << TAB << "return is;" << endl; + DEL_TAB; + s << TAB << "}" << endl; + + } + vector key = pPtr->getKey(); //定义< if (key.size() > 0) @@ -2344,6 +2519,7 @@ void Tars2Cpp::generateH(const ContextPtr &pPtr) const s << "#include " << endl; s << "#include " << endl; s << "#include \"tup/Tars.h\"" << endl; + if (_bJsonSupport) s << "#include \"tup/TarsJson.h\"" << endl; s << "using namespace std;" << endl; @@ -2381,24 +2557,24 @@ void Tars2Cpp::generateH(const ContextPtr &pPtr) const tars::TC_File::save2file(fileH, s.str()); } -void Tars2Cpp::createFile(const string& file, const vector& vsCoder) +void Tars2Cpp::createFile(const string& file)//, const vector& vsCoder) { std::vector contexts = g_parse->getContexts(); for (size_t i = 0; i < contexts.size(); i++) { if (file == contexts[i]->getFileName()) { - if (vsCoder.size() == 0) - { + // if (vsCoder.size() == 0) + // { generateH(contexts[i]); - } - else - { - for (size_t j = 0; j < vsCoder.size(); j++) - { - generateCoder(contexts[i], vsCoder[j]); - } - } + // } + // else + // { + // for (size_t j = 0; j < vsCoder.size(); j++) + // { + // generateCoder(contexts[i], vsCoder[j]); + // } + // } } } } @@ -2426,332 +2602,332 @@ StructPtr Tars2Cpp::findStruct(const ContextPtr& pPtr, const string& id) return NULL; } -//////////////////////////////// -//for coder generating -//////////////////////////////// - -string Tars2Cpp::generateCoder(const NamespacePtr& pPtr, const string& sInterface) const -{ - ostringstream s; - vector& is = pPtr->getAllInterfacePtr(); - vector& ss = pPtr->getAllStructPtr(); - vector& es = pPtr->getAllEnumPtr(); - vector& cs = pPtr->getAllConstPtr(); - - s << endl; - s << TAB << "namespace " << pPtr->getId() << endl; - s << TAB << "{" << endl; - INC_TAB; - - for (size_t i = 0; i < cs.size(); i++) - { - s << generateH(cs[i]) << endl; - } - - for (size_t i = 0; i < es.size(); i++) - { - s << generateH(es[i]) << endl; - } - - for (size_t i = 0; i < ss.size(); i++) - { - s << generateH(ss[i], pPtr->getId()) << endl; - } - - s << endl; - - for (size_t i = 0; i < is.size(); i++) - { - if (pPtr->getId() + "::" + is[i]->getId() == sInterface) - { - s << generateCoder(is[i]) << endl; - s << endl; - } - } - - DEL_TAB; - s << "}"; - - s << endl << endl; - - return s.str(); -} - -string Tars2Cpp::generateCoder(const InterfacePtr& pPtr) const -{ - ostringstream s; - - vector& vOperation = pPtr->getAllOperationPtr(); - - //生成编解码类 - s << TAB << "// encode and decode for client" << endl; - s << TAB << "class " << pPtr->getId() << "Coder" << endl; - s << TAB << "{" << endl; - s << TAB << "public:" << endl << endl; - INC_TAB; - s << TAB << "typedef map TARS_CONTEXT;" << endl << endl; - - s << TAB << "enum enumResult" << endl; - s << TAB << "{" << endl; - INC_TAB; - - s << TAB << "eTarsServerSuccess = 0," << endl; - s << TAB << "eTarsPacketLess = 1," << endl; - s << TAB << "eTarsPacketErr = 2," << endl; - s << TAB << "eTarsServerDecodeErr = -1," << endl; - s << TAB << "eTarsServerEncodeErr = -2," << endl; - s << TAB << "eTarsServerNoFuncErr = -3," << endl; - s << TAB << "eTarsServerNoServantErr = -4," << endl; - s << TAB << "eTarsServerQueueTimeout = -6," << endl; - s << TAB << "eTarsAsyncCallTimeout = -7," << endl; - s << TAB << "eTarsProxyConnectErr = -8," << endl; - s << TAB << "eTarsServerUnknownErr = -99," << endl; - - DEL_TAB; - s << TAB << "};" << endl << endl; - - for (size_t i = 0; i < vOperation.size(); i++) - { - s << generateCoder(vOperation[i]) << endl; - } - - DEL_TAB; - s << TAB << "protected:" << endl << endl; - INC_TAB; - s << TAB << "static " + _namespace + "::Int32 fetchPacket(const string & in, string & out)" << endl; - s << TAB << "{" << endl; - - INC_TAB; - s << TAB << "if(in.length() < sizeof(" + _namespace + "::Int32)) return eTarsPacketLess;" << endl; - - s << TAB << "" + _namespace + "::Int32 iHeaderLen;" << endl; - s << TAB << "memcpy(&iHeaderLen, in.c_str(), sizeof(" + _namespace + "::Int32));" << endl; - - s << TAB << "iHeaderLen = ntohl(iHeaderLen);" << endl; - s << TAB << "if(iHeaderLen < (" + _namespace + "::Int32)sizeof(" + _namespace + "::Int32) || iHeaderLen > 100000000) return eTarsPacketErr;" << endl; - s << TAB << "if((" + _namespace + "::Int32)in.length() < iHeaderLen) return eTarsPacketLess;" << endl; - - s << TAB << "out = in.substr(sizeof(" + _namespace + "::Int32), iHeaderLen - sizeof(" + _namespace + "::Int32)); " << endl; - s << TAB << "return 0;" << endl; - - DEL_TAB; - s << TAB << "}" << endl; - - s << endl; - s << TAB << "static string encodeBasePacket(const string & sServantName, const string & sFuncName, const vector & buffer, " - << "const map& context = TARS_CONTEXT())" << endl; - s << TAB << "{" << endl; - INC_TAB; - - s << TAB << _namespace + "::TarsOutputStream<" + _namespace + "::BufferWriter> os;" << endl; - s << TAB << "os.write(1, 1);" << endl; - s << TAB << "os.write(0, 2);" << endl; - s << TAB << "os.write(0, 3);" << endl; - s << TAB << "os.write(0, 4);" << endl; - s << TAB << "os.write(sServantName, 5);" << endl; - s << TAB << "os.write(sFuncName, 6);" << endl; - s << TAB << "os.write(buffer, 7);" << endl; - s << TAB << "os.write(60, 8);" << endl; - s << TAB << "os.write(context, 9);" << endl; - s << TAB << "os.write(map(), 10);" << endl; - - s << TAB << _namespace + "::Int32 iHeaderLen;" << endl; - s << TAB << "iHeaderLen = htonl(sizeof(" + _namespace + "::Int32) + os.getLength());" << endl; - s << TAB << "string s;" << endl; - s << TAB << "s.append((const char*)&iHeaderLen, sizeof(" + _namespace + "::Int32));" << endl; - s << TAB << "s.append(os.getBuffer(), os.getLength());" << endl; - - s << TAB << "return s;" << endl; - - DEL_TAB; - s << TAB << "}" << endl; - - s << endl; - s << TAB << "static " + _namespace + "::Int32 decodeBasePacket(const string & in, " + _namespace + "::Int32 & iServerRet, vector & buffer)" << endl; - s << TAB << "{" << endl; - INC_TAB; - - s << TAB << _namespace + "::TarsInputStream<" + _namespace + "::BufferReader> is;" << endl; - s << TAB << "is.setBuffer(in.c_str(), in.length());" << endl; - s << TAB << "is.read(iServerRet, 5, true);" << endl; - s << TAB << "is.read(buffer, 6, true);" << endl; - - s << TAB << "return 0;" << endl; - - DEL_TAB; - s << TAB << "}" << endl; - - s << endl; - - DEL_TAB; - s << TAB << "};" << endl; - - return s.str(); -} - -string Tars2Cpp::generateCoder(const OperationPtr& pPtr) const -{ - ostringstream s; - vector& vParamDecl = pPtr->getAllParamDeclPtr(); - - //编码函数 - s << TAB << "//encode & decode function for '" << pPtr->getId() << "()'" << endl << endl; - s << TAB << "static string encode_" << pPtr->getId() << "(const string & sServantName, "; - - for (size_t i = 0; i < vParamDecl.size(); i++) - { - if (!vParamDecl[i]->isOut()) - { - s << generateH(vParamDecl[i]) << ","; - } - } - s << endl; - s << TAB << " const map& context = TARS_CONTEXT())" << endl; - s << TAB << "{" << endl; - - INC_TAB; - s << TAB << "try" << endl; - s << TAB << "{" << endl; - - INC_TAB; - s << TAB << _namespace + "::TarsOutputStream<" + _namespace + "::BufferWriter> _os;" << endl; - - for (size_t i = 0; i < vParamDecl.size(); i++) - { - if (vParamDecl[i]->isOut()) continue; - s << writeTo(vParamDecl[i]->getTypeIdPtr()); - } +// //////////////////////////////// +// //for coder generating +// //////////////////////////////// + +// string Tars2Cpp::generateCoder(const NamespacePtr& pPtr, const string& sInterface) const +// { +// ostringstream s; +// vector& is = pPtr->getAllInterfacePtr(); +// vector& ss = pPtr->getAllStructPtr(); +// vector& es = pPtr->getAllEnumPtr(); +// vector& cs = pPtr->getAllConstPtr(); + +// s << endl; +// s << TAB << "namespace " << pPtr->getId() << endl; +// s << TAB << "{" << endl; +// INC_TAB; + +// for (size_t i = 0; i < cs.size(); i++) +// { +// s << generateH(cs[i]) << endl; +// } + +// for (size_t i = 0; i < es.size(); i++) +// { +// s << generateH(es[i]) << endl; +// } + +// for (size_t i = 0; i < ss.size(); i++) +// { +// s << generateH(ss[i], pPtr->getId()) << endl; +// } + +// s << endl; + +// for (size_t i = 0; i < is.size(); i++) +// { +// if (pPtr->getId() + "::" + is[i]->getId() == sInterface) +// { +// s << generateCoder(is[i]) << endl; +// s << endl; +// } +// } + +// DEL_TAB; +// s << "}"; + +// s << endl << endl; + +// return s.str(); +// } + +// string Tars2Cpp::generateCoder(const InterfacePtr& pPtr) const +// { +// ostringstream s; + +// vector& vOperation = pPtr->getAllOperationPtr(); + +// //生成编解码类 +// s << TAB << "// encode and decode for client" << endl; +// s << TAB << "class " << pPtr->getId() << "Coder" << endl; +// s << TAB << "{" << endl; +// s << TAB << "public:" << endl << endl; +// INC_TAB; +// s << TAB << "typedef map TARS_CONTEXT;" << endl << endl; + +// s << TAB << "enum enumResult" << endl; +// s << TAB << "{" << endl; +// INC_TAB; + +// s << TAB << "eTarsServerSuccess = 0," << endl; +// s << TAB << "eTarsPacketLess = 1," << endl; +// s << TAB << "eTarsPacketErr = 2," << endl; +// s << TAB << "eTarsServerDecodeErr = -1," << endl; +// s << TAB << "eTarsServerEncodeErr = -2," << endl; +// s << TAB << "eTarsServerNoFuncErr = -3," << endl; +// s << TAB << "eTarsServerNoServantErr = -4," << endl; +// s << TAB << "eTarsServerQueueTimeout = -6," << endl; +// s << TAB << "eTarsAsyncCallTimeout = -7," << endl; +// s << TAB << "eTarsProxyConnectErr = -8," << endl; +// s << TAB << "eTarsServerUnknownErr = -99," << endl; + +// DEL_TAB; +// s << TAB << "};" << endl << endl; + +// for (size_t i = 0; i < vOperation.size(); i++) +// { +// s << generateCoder(vOperation[i]) << endl; +// } + +// DEL_TAB; +// s << TAB << "protected:" << endl << endl; +// INC_TAB; +// s << TAB << "static " + _namespace + "::Int32 fetchPacket(const string & in, string & out)" << endl; +// s << TAB << "{" << endl; + +// INC_TAB; +// s << TAB << "if(in.length() < sizeof(" + _namespace + "::Int32)) return eTarsPacketLess;" << endl; + +// s << TAB << "" + _namespace + "::Int32 iHeaderLen;" << endl; +// s << TAB << "memcpy(&iHeaderLen, in.c_str(), sizeof(" + _namespace + "::Int32));" << endl; + +// s << TAB << "iHeaderLen = ntohl(iHeaderLen);" << endl; +// s << TAB << "if(iHeaderLen < (" + _namespace + "::Int32)sizeof(" + _namespace + "::Int32) || iHeaderLen > 100000000) return eTarsPacketErr;" << endl; +// s << TAB << "if((" + _namespace + "::Int32)in.length() < iHeaderLen) return eTarsPacketLess;" << endl; + +// s << TAB << "out = in.substr(sizeof(" + _namespace + "::Int32), iHeaderLen - sizeof(" + _namespace + "::Int32)); " << endl; +// s << TAB << "return 0;" << endl; + +// DEL_TAB; +// s << TAB << "}" << endl; + +// s << endl; +// s << TAB << "static string encodeBasePacket(const string & sServantName, const string & sFuncName, const vector & buffer, " +// << "const map& context = TARS_CONTEXT())" << endl; +// s << TAB << "{" << endl; +// INC_TAB; + +// s << TAB << _namespace + "::TarsOutputStream<" + _namespace + "::BufferWriter> os;" << endl; +// s << TAB << "os.write(1, 1);" << endl; +// s << TAB << "os.write(0, 2);" << endl; +// s << TAB << "os.write(0, 3);" << endl; +// s << TAB << "os.write(0, 4);" << endl; +// s << TAB << "os.write(sServantName, 5);" << endl; +// s << TAB << "os.write(sFuncName, 6);" << endl; +// s << TAB << "os.write(buffer, 7);" << endl; +// s << TAB << "os.write(60, 8);" << endl; +// s << TAB << "os.write(context, 9);" << endl; +// s << TAB << "os.write(map(), 10);" << endl; + +// s << TAB << _namespace + "::Int32 iHeaderLen;" << endl; +// s << TAB << "iHeaderLen = htonl(sizeof(" + _namespace + "::Int32) + os.getLength());" << endl; +// s << TAB << "string s;" << endl; +// s << TAB << "s.append((const char*)&iHeaderLen, sizeof(" + _namespace + "::Int32));" << endl; +// s << TAB << "s.append(os.getBuffer(), os.getLength());" << endl; + +// s << TAB << "return s;" << endl; + +// DEL_TAB; +// s << TAB << "}" << endl; + +// s << endl; +// s << TAB << "static " + _namespace + "::Int32 decodeBasePacket(const string & in, " + _namespace + "::Int32 & iServerRet, vector & buffer)" << endl; +// s << TAB << "{" << endl; +// INC_TAB; + +// s << TAB << _namespace + "::TarsInputStream<" + _namespace + "::BufferReader> is;" << endl; +// s << TAB << "is.setBuffer(in.c_str(), in.length());" << endl; +// s << TAB << "is.read(iServerRet, 5, true);" << endl; +// s << TAB << "is.read(buffer, 6, true);" << endl; + +// s << TAB << "return 0;" << endl; + +// DEL_TAB; +// s << TAB << "}" << endl; + +// s << endl; + +// DEL_TAB; +// s << TAB << "};" << endl; + +// return s.str(); +// } + +// string Tars2Cpp::generateCoder(const OperationPtr& pPtr) const +// { +// ostringstream s; +// vector& vParamDecl = pPtr->getAllParamDeclPtr(); + +// //编码函数 +// s << TAB << "//encode & decode function for '" << pPtr->getId() << "()'" << endl << endl; +// s << TAB << "static string encode_" << pPtr->getId() << "(const string & sServantName, "; + +// for (size_t i = 0; i < vParamDecl.size(); i++) +// { +// if (!vParamDecl[i]->isOut()) +// { +// s << generateH(vParamDecl[i]) << ","; +// } +// } +// s << endl; +// s << TAB << " const map& context = TARS_CONTEXT())" << endl; +// s << TAB << "{" << endl; + +// INC_TAB; +// s << TAB << "try" << endl; +// s << TAB << "{" << endl; + +// INC_TAB; +// s << TAB << _namespace + "::TarsOutputStream<" + _namespace + "::BufferWriter> _os;" << endl; + +// for (size_t i = 0; i < vParamDecl.size(); i++) +// { +// if (vParamDecl[i]->isOut()) continue; +// s << writeTo(vParamDecl[i]->getTypeIdPtr()); +// } - s << TAB << "return encodeBasePacket(sServantName, \"" << pPtr->getId() << "\", _os.getByteBuffer(), context);" << endl; +// s << TAB << "return encodeBasePacket(sServantName, \"" << pPtr->getId() << "\", _os.getByteBuffer(), context);" << endl; - DEL_TAB; - - s << TAB << "}" << endl; - s << TAB << "catch (" + _namespace + "::TarsException & ex)" << endl; - s << TAB << "{" << endl; - INC_TAB; - s << TAB << "return \"\";" << endl; - DEL_TAB; - s << TAB << "}" << endl; - DEL_TAB; - s << TAB << "}" << endl; - - s << endl; - - //解码函数 - - s << TAB << "static " + _namespace + "::Int32 decode_" << pPtr->getId() << "(const string & in "; +// DEL_TAB; + +// s << TAB << "}" << endl; +// s << TAB << "catch (" + _namespace + "::TarsException & ex)" << endl; +// s << TAB << "{" << endl; +// INC_TAB; +// s << TAB << "return \"\";" << endl; +// DEL_TAB; +// s << TAB << "}" << endl; +// DEL_TAB; +// s << TAB << "}" << endl; + +// s << endl; + +// //解码函数 + +// s << TAB << "static " + _namespace + "::Int32 decode_" << pPtr->getId() << "(const string & in "; - if (pPtr->getReturnPtr()->getTypePtr()) - { - s << ", " << tostr(pPtr->getReturnPtr()->getTypePtr()) << " & _ret "; - } - for (size_t i = 0; i < vParamDecl.size(); i++) - { - if(!vParamDecl[i]->isOut()) - continue; +// if (pPtr->getReturnPtr()->getTypePtr()) +// { +// s << ", " << tostr(pPtr->getReturnPtr()->getTypePtr()) << " & _ret "; +// } +// for (size_t i = 0; i < vParamDecl.size(); i++) +// { +// if(!vParamDecl[i]->isOut()) +// continue; - s << ", " << generateH(vParamDecl[i]); - } - s << ")" << endl; +// s << ", " << generateH(vParamDecl[i]); +// } +// s << ")" << endl; - s << TAB << "{" << endl; +// s << TAB << "{" << endl; - INC_TAB; - s << TAB << "try" << endl; - s << TAB << "{" << endl; +// INC_TAB; +// s << TAB << "try" << endl; +// s << TAB << "{" << endl; - INC_TAB; - s << TAB << "string out;" << endl; - s << TAB << _namespace + "::Int32 iRet = 0;" << endl; - s << TAB << "if((iRet = fetchPacket(in, out)) != 0) return iRet;" << endl; +// INC_TAB; +// s << TAB << "string out;" << endl; +// s << TAB << _namespace + "::Int32 iRet = 0;" << endl; +// s << TAB << "if((iRet = fetchPacket(in, out)) != 0) return iRet;" << endl; - s << TAB << _namespace + "::TarsInputStream<" + _namespace + "::BufferReader> _is;" << endl; - s << TAB << _namespace + "::Int32 iServerRet=0;" << endl; - s << TAB << "vector buffer;" << endl; - s << TAB << "decodeBasePacket(out, iServerRet, buffer);" << endl; - s << TAB << "if(iServerRet != 0) return iServerRet;" << endl; +// s << TAB << _namespace + "::TarsInputStream<" + _namespace + "::BufferReader> _is;" << endl; +// s << TAB << _namespace + "::Int32 iServerRet=0;" << endl; +// s << TAB << "vector buffer;" << endl; +// s << TAB << "decodeBasePacket(out, iServerRet, buffer);" << endl; +// s << TAB << "if(iServerRet != 0) return iServerRet;" << endl; - s << TAB << "_is.setBuffer(buffer);" << endl; +// s << TAB << "_is.setBuffer(buffer);" << endl; - if (pPtr->getReturnPtr()->getTypePtr()) - { - s << readFrom(pPtr->getReturnPtr()); - } +// if (pPtr->getReturnPtr()->getTypePtr()) +// { +// s << readFrom(pPtr->getReturnPtr()); +// } - for (size_t i = 0; i < vParamDecl.size(); i++) - { - if (vParamDecl[i]->isOut()) - { - s << readFrom(vParamDecl[i]->getTypeIdPtr()); - } - } +// for (size_t i = 0; i < vParamDecl.size(); i++) +// { +// if (vParamDecl[i]->isOut()) +// { +// s << readFrom(vParamDecl[i]->getTypeIdPtr()); +// } +// } - s << TAB << "return 0;" << endl; +// s << TAB << "return 0;" << endl; - DEL_TAB; - s << TAB << "}" << endl; - s << TAB << "catch (" + _namespace + "::TarsException & ex)" << endl; - s << TAB << "{" << endl; - INC_TAB; - s << TAB << "return eTarsPacketErr;" << endl; - DEL_TAB; - s << TAB << "}" << endl; +// DEL_TAB; +// s << TAB << "}" << endl; +// s << TAB << "catch (" + _namespace + "::TarsException & ex)" << endl; +// s << TAB << "{" << endl; +// INC_TAB; +// s << TAB << "return eTarsPacketErr;" << endl; +// DEL_TAB; +// s << TAB << "}" << endl; - DEL_TAB; - s << TAB << "}" << endl; +// DEL_TAB; +// s << TAB << "}" << endl; - s << endl; +// s << endl; - return s.str(); -} +// return s.str(); +// } -void Tars2Cpp::generateCoder(const ContextPtr& pPtr, const string& sInterface) const -{ - cout << "Interface:" << sInterface << endl; - string n = tars::TC_File::excludeFileExt(tars::TC_File::extractFileName(pPtr->getFileName())) + "Coder"; +// void Tars2Cpp::generateCoder(const ContextPtr& pPtr, const string& sInterface) const +// { +// cout << "Interface:" << sInterface << endl; +// string n = tars::TC_File::excludeFileExt(tars::TC_File::extractFileName(pPtr->getFileName())) + "Coder"; - string fileH = _baseDir + "/" + n + ".h"; +// string fileH = _baseDir + "/" + n + ".h"; - string define = tars::TC_Common::upper("__" + n + "_h_"); +// string define = tars::TC_Common::upper("__" + n + "_h_"); - ostringstream s; +// ostringstream s; - s << g_parse->printHeaderRemark(); +// s << g_parse->printHeaderRemark(); - s << "#ifndef " << define << endl; - s << "#define " << define << endl; - s << endl; - s << "#include " << endl; - s << "#include " << endl; - s << "#include " << endl; - s << "#include \"tup/Tars.h\"" << endl; +// s << "#ifndef " << define << endl; +// s << "#define " << define << endl; +// s << endl; +// s << "#include " << endl; +// s << "#include " << endl; +// s << "#include " << endl; +// s << "#include \"tup/Tars.h\"" << endl; - s << "using namespace std;" << endl; +// s << "using namespace std;" << endl; - vector include = pPtr->getIncludes(); - for (size_t i = 0; i < include.size(); i++) - { - s << "#include \"" << g_parse->getHeader() - << tars::TC_Common::replace(tars::TC_File::extractFileName(include[i]), ".h", "Coder.h") << "\"" << endl; - } +// vector include = pPtr->getIncludes(); +// for (size_t i = 0; i < include.size(); i++) +// { +// s << "#include \"" << g_parse->getHeader() +// << tars::TC_Common::replace(tars::TC_File::extractFileName(include[i]), ".h", "Coder.h") << "\"" << endl; +// } - vector namespaces = pPtr->getNamespaces(); +// vector namespaces = pPtr->getNamespaces(); - s << endl; +// s << endl; - for (size_t i = 0; i < namespaces.size(); i++) - { - s << generateCoder(namespaces[i], sInterface) << endl; - } +// for (size_t i = 0; i < namespaces.size(); i++) +// { +// s << generateCoder(namespaces[i], sInterface) << endl; +// } - s << endl; - s << "#endif" << endl; +// s << endl; +// s << "#endif" << endl; - tars::TC_File::makeDirRecursive(_baseDir, 0755); - tars::TC_File::save2file(fileH, s.str()); +// tars::TC_File::makeDirRecursive(_baseDir, 0755); +// tars::TC_File::save2file(fileH, s.str()); - return; -} +// return; +// } diff --git a/tools/tars2cpp/tars2cpp.h b/tools/tars2cpp/tars2cpp.h index 25bae66..b9191f8 100644 --- a/tools/tars2cpp/tars2cpp.h +++ b/tools/tars2cpp/tars2cpp.h @@ -38,7 +38,7 @@ public: * 生成 * @param file */ - void createFile(const string &file, const vector &vsCoder); + void createFile(const string &file);//, const vector &vsCoder); /** * 设置生成文件的目录 @@ -51,6 +51,11 @@ public: */ void setCheckDefault(bool bCheck) { _checkDefault = bCheck; } + /** + * 根据命令选项设置是否需要生成json支持 + */ + void setJsonSupport(bool bJsonSupport) { _bJsonSupport = bJsonSupport; } + /** * 设置是否只生成struct */ @@ -70,6 +75,22 @@ public: //下面是编解码的源码生成 protected: + /** + * 生成json + * @param pPtr + * + * @return string + */ + string writeToJson(const TypeIdPtr& pPtr) const; + + /** + * 生成json + * @param pPtr + * + * @return string + */ + string readFromJson(const TypeIdPtr& pPtr, bool bIsRequire = true) const; + /** * 生成某类型的解码源码 * @param pPtr @@ -403,19 +424,19 @@ protected: */ StructPtr findStruct(const ContextPtr &pPtr,const string &id); - /** - * - * 生成接口编解码代码 - * @param pPtr - * @param interface - */ - void generateCoder(const ContextPtr &pPtr,const string &interface) const; + // /** + // * + // * 生成接口编解码代码 + // * @param pPtr + // * @param interface + // */ + // void generateCoder(const ContextPtr &pPtr,const string &interface) const; - string generateCoder(const NamespacePtr &pPtr,const string & sInterface) const; + // string generateCoder(const NamespacePtr &pPtr,const string & sInterface) const; - string generateCoder(const InterfacePtr &pPtr) const; + // string generateCoder(const InterfacePtr &pPtr) const; - string generateCoder(const OperationPtr &pPtr) const; + // string generateCoder(const OperationPtr &pPtr) const; string generateInitValue(const TypeIdPtr &pPtr) const; @@ -428,6 +449,8 @@ private: bool _onlyStruct; + bool _bJsonSupport; + std::string _namespace ; bool _unknownField; diff --git a/util/include/util/tc_json.h b/util/include/util/tc_json.h new file mode 100644 index 0000000..fcfd0df --- /dev/null +++ b/util/include/util/tc_json.h @@ -0,0 +1,259 @@ +#ifndef __TC_JSON_H +#define __TC_JSON_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util/tc_autoptr.h" + +using namespace std; + +namespace tars +{ + +///////////////////////////////////////////////// +// 说明: json编解码的公共库 +// Author : zhangcunli@tencent.com +///////////////////////////////////////////////// + +/** +* 编解码抛出的异常 +*/ +struct TC_Json_Exception : public TC_Exception +{ + TC_Json_Exception(const string &buffer) : TC_Exception(buffer){}; + ~TC_Json_Exception() throw(){}; +}; + +enum eJsonType +{ + eJsonTypeString, + eJsonTypeNum, + eJsonTypeObj, + eJsonTypeArray, + eJsonTypeBoolean, + eJsonTypeNull, +}; + +/* + * 分析json字符串用到的 读字符的类 + */ +class BufferJsonReader +{ + const char * _buf; ///< 缓冲区 + size_t _buf_len; ///< 缓冲区长度 + size_t _cur; ///< 当前位置 + +public: + + BufferJsonReader () :_buf(NULL),_buf_len(0), _cur(0) {} + + void reset() { _cur = 0;} + + void setBuffer(const char * buf, size_t len) + { + _buf = buf; + _buf_len = len; + _cur = 0; + } + + void setBuffer(const std::vector &buf) + { + _buf = buf.data(); + _buf_len = buf.size(); + _cur = 0; + } + + const size_t &getCur() const { return _cur; } + + const char * getPoint() const { return _buf+_cur; } + + const char &read() { check(); _cur ++; return *(_buf+_cur-1); } + + const char &get() const { check(); return *(_buf+_cur); } + + const char &getBack() const { assert(_cur>0); return *(_buf+_cur-1); } + + void back() { assert(_cur>0); _cur--; } + + void check() const + { + if (_cur + 1 > _buf_len) + { + char s[64]; + snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)_buf_len); + throw TC_Json_Exception(s); + } + } + + bool hasEnd() const { return _cur >= _buf_len; } +}; + +class JsonValue; +class JsonValueObj; +class JsonValueArray; +class JsonValueString; +class JsonValueBoolean; +class JsonValueNum; +class JsonValueNull; + +typedef TC_AutoPtr JsonValuePtr; +typedef TC_AutoPtr JsonValueObjPtr; +typedef TC_AutoPtr JsonValueNumPtr; +typedef TC_AutoPtr JsonValueArrayPtr; +typedef TC_AutoPtr JsonValueStringPtr; +typedef TC_AutoPtr JsonValueBooleanPtr; +typedef TC_AutoPtr JsonValueNullPtr; + +/* + * json类型的基类。没有任何意义 + */ +class JsonValue : public TC_HandleBase +{ +public: + virtual eJsonType getType() const = 0; + virtual void write(ostream& ostr) const; + virtual void read(BufferJsonReader & reader, char c) = 0; + virtual ~JsonValue() { } + +public: + static JsonValuePtr createJsonValue(BufferJsonReader & reader); + static uint32_t getHex(BufferJsonReader & reader); + static bool isspace(char c); + static void writeString(const string &str, ostream& ostr); + +protected: + JsonValue(){}; +}; + +/* + * json类型 string类型 例如"dd\ndfd" + */ +class JsonValueString : public JsonValue +{ +public: + JsonValueString(const string & s):value(s) + { + } + JsonValueString() + { + } + + eJsonType getType() const { return eJsonTypeString; } + + virtual void write(ostream& ostr) const; + virtual void read(BufferJsonReader & reader, char c); + + virtual ~JsonValueString() { } + string value; +}; + +/* + * json类型 number类型 例如 1.5e8 + */ +class JsonValueNum : public JsonValue +{ +public: + JsonValueNum(double d,bool b=false):value(d),isInt(b) + { + } + JsonValueNum() + { + isInt=false; + value=0.0f; + } + eJsonType getType() const { return eJsonTypeNum; } + virtual void write(ostream& ostr) const; + virtual void read(BufferJsonReader & reader, char c); + + virtual ~JsonValueNum(){} +public: + double value; + bool isInt; +}; + +/* + * json类型 object类型 例如 {"aa","bb"} + */ +class JsonValueObj: public JsonValue +{ +public: + eJsonType getType() const { return eJsonTypeObj; } + virtual void write(ostream& ostr) const; + virtual void read(BufferJsonReader & reader, char c); + const JsonValuePtr &get(const char *name); + virtual ~JsonValueObj(); +public: + unordered_map value; +}; + +/* + * json类型 array类型 例如 ["aa","bb"] + */ +class JsonValueArray: public JsonValue +{ +public: + eJsonType getType() const { return eJsonTypeArray; } + void push_back(const JsonValuePtr & p) { value.push_back(p); } + virtual void write(ostream& ostr) const; + virtual void read(BufferJsonReader & reader, char c = 0); + virtual ~JsonValueArray(); +public: + vector value; +}; + +/* + * json类型 boolean类型 例如 true + */ +class JsonValueBoolean : public JsonValue +{ +public: + eJsonType getType() const { return eJsonTypeBoolean; } + bool getValue() const { return value; } + virtual void write(ostream& ostr) const; + virtual void read(BufferJsonReader & reader,char c); + virtual ~JsonValueBoolean(){} +public: + bool value; +}; + +/* + * json类型 null类型 例如"dd\ndfd" + */ +class JsonValueNull : public JsonValue +{ +public: + JsonValueNull() { } + + eJsonType getType() const { return eJsonTypeNull; } + + virtual void write(ostream& ostr) const; + virtual void read(BufferJsonReader & reader, char c); + + virtual ~JsonValueNull() { } +}; + +/* + * 分析json的类。都是static + */ +class TC_Json +{ +public: + //json类型到字符串的转换 + static string writeValue(const JsonValuePtr &p); + + //解析成智能指针 + static JsonValuePtr getValue(const string & str); + +}; + +} + +#endif + diff --git a/util/src/tc_json.cpp b/util/src/tc_json.cpp new file mode 100644 index 0000000..f56e982 --- /dev/null +++ b/util/src/tc_json.cpp @@ -0,0 +1,626 @@ +#include "util/tc_json.h" + +#include +#include +#include +#include +#include "util/tc_common.h" + +namespace tars +{ + +#define FILTER_SPACE while(isspace((int)c)) {c=reader.read();} + +//json里面定义的空白字符 +bool JsonValue::isspace(char c) +{ + if(c == ' ' || c == '\t' || c == '\r' || c == '\n') + return true; + return false; +} + +uint32_t JsonValue::getHex(BufferJsonReader & reader) +{ + uint32_t iCode=0; + char c; + for(int iLoop=0;iLoop<4;iLoop++) + { + c=reader.read(); + if(c>='a'&&c<='f') + iCode=iCode*16+c-'a'+10; + else if(c>='A'&&c<='F') + iCode=iCode*16+c-'A'+10; + else if(c>='0'&&c<='9') + iCode=iCode*16+c-'0'; + else + { + char s[64]; + snprintf(s, sizeof(s), "get string error3(\\u)[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + } + return iCode; +} + +void JsonValue::writeString(const string &str, ostream& ostr) +{ + ostr << "\""; + std::string::const_iterator it(str.begin()), itEnd(str.end()); + for (; it != itEnd; ++it) + { + switch(*it) + { + case '"': + ostr << "\\\""; + break; + case '\\': + ostr << "\\\\"; + break; + case '/': + ostr << "\\/"; + break; + case '\b': + ostr << "\\b"; + break; + case '\f': + ostr << "\\f"; + break; + case '\n': + ostr << "\\n"; + break; + case '\r': + ostr << "\\r"; + break; + case '\t': + ostr << "\\t"; + break; + default: + { + if((unsigned char)(*it)<0x20) + { + char buf[16]; + snprintf(buf,sizeof(buf),"\\u%04x",(unsigned char)*it); + ostr << string(buf,6); + } + else + { + ostr << *it; + } + break; + } + } + } + ostr << "\""; +} + +void JsonValue::write(ostream& ostr) const +{ + switch(getType()) + { + case eJsonTypeString: + dynamic_cast(this)->write(ostr); + break; + case eJsonTypeNum: + dynamic_cast(this)->write(ostr); + break; + case eJsonTypeObj: + dynamic_cast(this)->write(ostr); + break; + case eJsonTypeArray: + dynamic_cast(this)->write(ostr); + break; + case eJsonTypeBoolean: + dynamic_cast(this)->write(ostr); + break; + case eJsonTypeNull: + dynamic_cast(this)->write(ostr); + break; + default: + assert(false); + } + +} + +JsonValuePtr JsonValue::createJsonValue(BufferJsonReader & reader) +{ + char c = reader.read(); + + FILTER_SPACE; + + JsonValue* obj = NULL; + switch(c) + { + case '{': + obj = new JsonValueObj(); + break; + case '[': + obj = new JsonValueArray(); + break; + case '"': + obj = new JsonValueString(); + break; + case 'T': + case 't': + case 'F': + case 'f': + obj = new JsonValueBoolean(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + obj = new JsonValueNum(); + break; + case 'n': + case 'N': + obj = new JsonValueNull(); + break; + default: + char s[64]; + snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + obj->read(reader, c); + + return obj; + } + +void JsonValueString::write(ostream& ostr) const +{ + writeString(value, ostr); +} + +void JsonValueString::read(BufferJsonReader & reader, char head) +{ + const char * pChar=reader.getPoint(); + uint32_t i=0; + while(1) + { + char c = reader.read(); + if(c == '\\') + { + value.append(pChar,i); + pChar=pChar+i+2; + i=0; + c=reader.read(); + switch(c) + { + case '\\': + case '\"': + case '/': + value.append(1, c); + break; + case 'b': + value.append(1,'\b'); + break; + case 'f': + value.append(1,'\f'); + break; + case 'n': + value.append(1,'\n'); + break; + case 'r': + value.append(1,'\r'); + break; + case 't': + value.append(1,'\t'); + break; + case 'u': + // } + // if(c == '\\' || c == '\"' || c == '/') + // value.append(1,c); + // else if(c == 'b') + // value.append(1,'\b'); + // else if(c == 'f') + // value.append(1,'\f'); + // else if(c == 'n') + // value.append(1,'\n'); + // else if(c == 'r') + // value.append(1,'\r'); + // else if(c == 't') + // value.append(1,'\t'); + // else if(c == 'u') + { + uint32_t iCode=getHex(reader); + + if (iCode < 0x00080) + { + value.append(1,(char)(iCode & 0xFF)); + } + else if (iCode < 0x00800) + { + value.append(1,(char)(0xC0 + ((iCode >> 6) & 0x1F))); + value.append(1,(char)(0x80 + (iCode & 0x3F))); + } + else if (iCode < 0x10000) + { + value.append(1,(char)(0xE0 + ((iCode >> 12) & 0x0F))); + value.append(1,(char)(0x80 + ((iCode >> 6) & 0x3F))); + value.append(1,(char)(0x80 + (iCode & 0x3F))); + } + else + { + value.append(1,(char)(0xF0 + ((iCode >> 18) & 0x07))); + value.append(1,(char)(0x80 + ((iCode >> 12) & 0x3F))); + value.append(1,(char)(0x80 + ((iCode >> 6) & 0x3F))); + value.append(1,(char)(0x80 + (iCode & 0x3F))); + } + pChar+=4; + } + } + } + else if(c==head) + break; + else + i++; + } + value.append(pChar,i); +} + +void JsonValueNum::write(ostream& ostr) const +{ + if (!isInt) + { + ostr << TC_Common::tostr(value); + } + else + { + ostr << (int64_t)value; + } +} + +void JsonValueNum::read(BufferJsonReader & reader, char head) +{ + bool bOk=true; + bool bFloat=false; + bool bExponential=false; + bool bNegative=false; + bool bExponentialNegative=false; + int64_t iInt=0; + double dFloat=0; + double dFloatRat=0; + int64_t iExponential=0; + if(head == '-') + { + bOk=false; + bNegative=true; + } + else + iInt=head-0x30; + + char c; + bool bNeedBack=false; + + while(1) + { + if(reader.hasEnd()) + break; + c=reader.read(); + if(c>=0x30 && c<=0x39) + { + bOk=true; + if(bExponential) + iExponential=iExponential*10+c-0x30; + else if(bFloat) + { + dFloat=dFloat+dFloatRat*(c-0x30); + dFloatRat=dFloatRat*0.1; + } + else + iInt=iInt*10+c-0x30; + } + else if(c == '.' && !bFloat && !bExponential && bOk) + { + bOk=false; + bFloat=true; + dFloatRat=0.1; + } + else if((c == 'e' || c == 'E') && !bExponential && bOk) + { + bOk=false; + bExponential=true; + iExponential=0; + if(reader.hasEnd()) + break; + c=reader.read(); + if(c == '-') + bExponentialNegative=true; + else if(c == '+') + bExponentialNegative=false; + else if(c>=0x30 && c<=0x39) + { + bOk=true; + bExponential=(bool)(c-0x30); + } + else + { + bNeedBack=true; + break; + } + } + else + { + bNeedBack=true; + break; + } + } + if(!bOk) + { + char s[64]; + snprintf(s, sizeof(s), "get num error[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + if(bNeedBack) + reader.back(); + if(bExponentialNegative) + iExponential=0-iExponential; + double dResult=(iInt+dFloat)*pow(10,iExponential); + if(bNegative) + dResult=0-dResult; + + this->value=dResult; +} + +JsonValueObj::~JsonValueObj() +{ + // for(auto it = value.begin(); it != value.end(); ++it) + // { + // delete it->second; + // } + // value.clear(); +} + +const JsonValuePtr& JsonValueObj::get(const char *name) +{ + auto it = value.find(name); + + if(it == value.end()) + { + char s[64]; + snprintf(s, sizeof(s), "get obj error(key is not exists)[key:%s]", name); + throw TC_Json_Exception(s); + } + + return it->second; +} + +void JsonValueObj::write(ostream& ostr) const +{ + ostr << "{ "; + auto it = value.begin(); //unordered_map::const_iterator it(value.begin()), it_end(value.end()); + while (it != value.end()) + { + writeString(it->first, ostr); + + ostr << ": " ; + + it->second->write(ostr); + if(++it != value.end()) + { + ostr << ", "; + } + } + ostr << " }"; +} + +void JsonValueObj::read(BufferJsonReader & reader, char cc) +{ + bool bFirst=true; + while(1) + { + char c=reader.read(); + FILTER_SPACE; + if(c == '}' && bFirst) + { + return; + } + bFirst=false; + + if(c != '"') + { + char s[64]; + snprintf(s, sizeof(s), "get obj error(key is not string)[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + + JsonValueString vs; + vs.read(reader, c); + + c=reader.read(); + FILTER_SPACE; + if(c != ':') + { + char s[64]; + snprintf(s, sizeof(s), "get obj error(: not find)[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } + + value.insert(make_pair(vs.value, JsonValue::createJsonValue(reader))); + + c=reader.read(); + FILTER_SPACE; + + if(c == ',') continue; + + if(c == '}') + { + return; + } + + char s[64]; + snprintf(s, sizeof(s), "get obj error(, not find)[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } +} + +JsonValueArray::~JsonValueArray() +{ + // for(auto it = value.begin(); it != value.end(); ++it) + // { + // delete *it; + // } + // value.clear(); +} + +void JsonValueArray::write(ostream& ostr) const +{ + ostr << "[ "; + auto it = value.begin(); //vector::const_iterator it(value.begin()), it_end(value.end()); + while (it != value.end()) + { + (*it)->write(ostr); + + if (++it != value.end()) + { + ostr << ", "; + } + } + ostr << " ]"; +} + +void JsonValueArray::read(BufferJsonReader & reader, char cc) +{ + bool bFirst=true; + while(1) + { + char c; + if(bFirst) + { + c=reader.read(); + FILTER_SPACE; + if(c == ']') + { + return; + } + reader.back(); + } + bFirst=false; + + this->push_back(JsonValue::createJsonValue(reader)); + + c=reader.read(); + FILTER_SPACE; + if(c == ',') + continue; + if(c == ']') + return; + + char s[64]; + snprintf(s, sizeof(s), "get vector error(, not find )[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } +} + +void JsonValueBoolean::write(ostream& ostr) const +{ + if(value) + ostr << "true"; + else + ostr << "false"; +} + +//为了提高效率和代码好写就先这么写了 +void JsonValueBoolean::read(BufferJsonReader & reader, char c) +{ + bool bOk=false; + // bool bValue; + if(c=='t'||c=='T') + { + c=reader.read(); + if(c=='r'||c=='R') + { + c=reader.read(); + if(c=='u'||c=='U') + { + c=reader.read(); + if(c=='e'||c=='E') + { + value=true; + bOk=true; + } + } + } + } + else if(c=='f'||c=='F') + { + c=reader.read(); + if(c=='a'||c=='A') + { + c=reader.read(); + if(c=='l'||c=='L') + { + c=reader.read(); + if(c=='s'||c=='S') + { + c=reader.read(); + if(c=='e'||c=='E') + { + value=false; + bOk=true; + } + } + } + } + } + + if(!bOk) + { + char s[64]; + snprintf(s, sizeof(s), "get bool error[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } +} + +void JsonValueNull::write(ostream& ostr) const +{ + ostr << "null"; +} + +void JsonValueNull::read(BufferJsonReader & reader, char c) +{ + assert(c=='n' || c=='N'); + bool bOk=false; + c=reader.read(); + if(c=='u'||c=='U') + { + c=reader.read(); + if(c=='l'||c=='L') + { + c=reader.read(); + if(c=='l'||c=='L') + { + bOk=true; + } + } + } + if(!bOk) + { + char s[64]; + snprintf(s, sizeof(s), "get NULL error[pos:%u]", (uint32_t)reader.getCur()); + throw TC_Json_Exception(s); + } +} + +string TC_Json::writeValue(const JsonValuePtr& p) +{ + ostringstream ostr; + p->write(ostr); + return ostr.str(); +} + +JsonValuePtr TC_Json::getValue(const string & str) +{ + BufferJsonReader reader; + reader.setBuffer(str.c_str(),str.length()); + return JsonValue::createJsonValue(reader); +} + +} +