#include "stdafx.h" #if (defined _WIN32 || defined _WIN64) #else #include "SpUtility.h" #include "../../ThirdParty/Include/CJson/cJSON.h" #include #include #endif #include "uuid4.h" #include "BufferOperation.h" #include "modp_b64.h" #include "SpBase.h" #include "SpHelper.h" #include "CWSCodec.h" #include "MessageType.h" #include "Chromium_msg_g.h" #include #include #include #include #include "baseEx.h" #define DEFAULT_CAPACITY 20480 namespace Chromium { static inline bool is_base64(CSimpleStringA str) { int num = str.GetLength() % 4; CSimpleStringA endStr = ""; if (0 == num) return true; for (int i = 0; i < num; ++i) { endStr.Append("="); } return str.IsEndWith(endStr); } CWSCodec::CWSCodec() :m_DeserializeCache(MAX_TRANSFER_LEN), m_SerializeCache(MAX_TRANSFER_LEN) { } CWSCodec::~CWSCodec() { if (mInterpreter) { delete this->mInterpreter; } } CWSCodec* CWSCodec::getInstance() { //DbgEx("CWSCodec static method getInstance"); static CWSCodec obj; return &obj; } bool CWSCodec::checkEntityHasService(std::string entityName) { if (!mInterpreter) return true;//默认有service return mInterpreter->checkEntityInservice(entityName); } void CWSCodec::setEntityHandler(CSmartPointer p) { this->m_pFunc = p; } void CWSCodec::init(const char* xmlPath) { DbgEx("CWSCodec method -> init from %s", xmlPath); try { mInterpreter = new CStructureInterpreter(xmlPath); } catch (const std::bad_alloc& e) { DbgEx("CWSCodec::init Memory allocation failed: %s", e.what()); } catch (const std::exception& e) { DbgEx("CWSCodec::init Error: %s", e.what()); } } void CWSCodec::DeserializeBase(CMessage& msg, CTransStruct& ts, int& rpos, cJSON* ret) { std::list::iterator i = ts.mParamList.begin(); auto deleteCjson = [](cJSON* dst) { if (NULL != dst) cJSON_Delete(dst); }; std::unique_ptr extendJs(cJSON_CreateObject(), deleteCjson); std::string t_arr[] = { "messageType", "sessionID", "transID", "isEnd", "errorCode", "errorMsg" }; std::vector c_repeatParamList(t_arr, t_arr + sizeof(t_arr) / sizeof(t_arr[0])); #if (defined _WIN32 || defined _WIN64) for each (auto paramInfo in ts.mParamList) { for each (auto repeatName in c_repeatParamList) { #else for (auto paramInfo : ts.mParamList) { for (auto repeatName : c_repeatParamList) { #endif if (paramInfo.mName == repeatName) DbgEx("requestAck参数名字重复, error, %s", paramInfo.mName.c_str()); } } //存在脏数据,不做另外处理 try { while (i != ts.mParamList.end()) { bool t_isRepeat = false; #if (defined _WIN32 || defined _WIN64) for each (auto repeatName in c_repeatParamList) #else for (auto repeatName : c_repeatParamList) #endif { if (i->mName == repeatName) { DbgEx("requestAck参数名字重复, error, %s", i->mName); t_isRepeat = true; } } if (i->mType == "int") { int d = 0; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddNumberToObject(ret, i->mName.c_str(), d); cJSON_AddNumberToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "uint") { unsigned int d = 0; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddNumberToObject(ret, i->mName.c_str(), d); cJSON_AddNumberToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "short") { short d = 0; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddNumberToObject(ret, i->mName.c_str(), d); cJSON_AddNumberToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "ushort") { unsigned short d = 0; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddNumberToObject(ret, i->mName.c_str(), d); cJSON_AddNumberToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "char") { char d = 0; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddNumberToObject(ret, i->mName.c_str(), d); cJSON_AddNumberToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "uchar") { unsigned char d = 0; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddNumberToObject(ret, i->mName.c_str(), d); cJSON_AddNumberToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "int64") { __int64 d = 0; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddNumberToObject(ret, i->mName.c_str(), d); cJSON_AddNumberToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "uint64") { #if (defined _WIN32 || defined _WIN64) unsigned __int64 d = 0; #else u_int64_t d = 0; #endif ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddNumberToObject(ret, i->mName.c_str(), d); cJSON_AddNumberToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "bool") { bool d = false; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddBoolToObject(ret, i->mName.c_str(), d); cJSON_AddNumberToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "double") { double d = false; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddNumberToObject(ret, i->mName.c_str(), d); cJSON_AddNumberToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "string") { CSimpleStringA d = ""; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddStringToObject(ret, i->mName.c_str(), d); cJSON_AddStringToObject(extendJs.get(), i->mName.c_str(), d); } else if (i->mType == "wstring") { CSimpleStringW d = ""; ReadT(msg.getPayload(), d, &rpos); if (!t_isRepeat) cJSON_AddStringToObject(ret, i->mName.c_str(), CSimpleStringW2A(d)); cJSON_AddStringToObject(extendJs.get(), i->mName.c_str(), CSimpleStringW2A(d)); } else if (i->mType == "blob") { int len = 0; void* binData = NULL; char* base64Data = NULL; ReadT(msg.getPayload(), len, &rpos); if (0 != len) {//协商好,H5对blob数据进行base64加密,chromium这里进行base64解密 binData = (char*)malloc(sizeof(char) * len); ReadT(msg.getPayload(), binData, len, &rpos); int base64Len = modp_b64_encode_len(len); base64Data = (char*)malloc(sizeof(char) * base64Len); modp_b64_encode(base64Data, (const char*)binData, len); if (!t_isRepeat) cJSON_AddStringToObject(ret, i->mName.c_str(), base64Data); cJSON_AddStringToObject(extendJs.get(), i->mName.c_str(), base64Data); if (binData != NULL) { free(binData); binData = NULL; } if (base64Data != NULL) { free(base64Data); base64Data = NULL; } } else { if (!t_isRepeat) cJSON_AddStringToObject(ret, i->mName.c_str(), ""); cJSON_AddStringToObject(extendJs.get(), i->mName.c_str(), ""); } } else if (i->mType == "array_int") { int len = 0; int d = 0; ReadT(msg.getPayload(), len, &rpos); cJSON* tmpArray = cJSON_CreateArray(), * tmpArray2 = cJSON_CreateArray(); for (int c = 0; c < len; ++c) { ReadT(msg.getPayload(), d, &rpos); cJSON_AddItemToArray(tmpArray, cJSON_CreateNumber(d)); cJSON_AddItemToArray(tmpArray2, cJSON_CreateNumber(d)); } if (!t_isRepeat) cJSON_AddItemToObject(ret, i->mName.c_str(), tmpArray); cJSON_AddItemToObject(extendJs.get(), i->mName.c_str(), tmpArray2); } else if (i->mType == "array_bool") { int len = 0; bool d = 0; ReadT(msg.getPayload(), len, &rpos); cJSON* tmpArray = cJSON_CreateArray(), * tmpArray2 = cJSON_CreateArray(); for (int c = 0; c < len; ++c) { ReadT(msg.getPayload(), d, &rpos); cJSON_AddItemToArray(tmpArray, cJSON_CreateBool(d)); cJSON_AddItemToArray(tmpArray2, cJSON_CreateBool(d)); } if (!t_isRepeat) cJSON_AddItemToObject(ret, i->mName.c_str(), tmpArray); cJSON_AddItemToObject(extendJs.get(), i->mName.c_str(), tmpArray2); } else if (i->mType == "array_uint") { int len = 0; unsigned int d = 0; ReadT(msg.getPayload(), len, &rpos); cJSON* tmpArray = cJSON_CreateArray(), * tmpArray2 = cJSON_CreateArray(); for (int c = 0; c < len; ++c) { ReadT(msg.getPayload(), d, &rpos); cJSON_AddItemToArray(tmpArray, cJSON_CreateNumber(d)); cJSON_AddItemToArray(tmpArray2, cJSON_CreateNumber(d)); } if (!t_isRepeat) cJSON_AddItemToObject(ret, i->mName.c_str(), tmpArray); cJSON_AddItemToObject(extendJs.get(), i->mName.c_str(), tmpArray2); } else if (i->mType == "array_uint64") { int len = 0; #if (defined _WIN32 || defined _WIN64) unsigned __int64 d = 0; #else u_int64_t d = 0; #endif ReadT(msg.getPayload(), len, &rpos); cJSON* tmpArray = cJSON_CreateArray(), * tmpArray2 = cJSON_CreateArray(); for (int c = 0; c < len; c++) { ReadT(msg.getPayload(), d, &rpos); cJSON_AddItemToArray(tmpArray, cJSON_CreateNumber(d)); cJSON_AddItemToArray(tmpArray2, cJSON_CreateNumber(d)); } if (!t_isRepeat) cJSON_AddItemToObject(ret, i->mName.c_str(), tmpArray); cJSON_AddItemToObject(extendJs.get(), i->mName.c_str(), tmpArray2); } else if (i->mType == "array_string") { int len = 0; CSimpleStringA d = ""; ReadT(msg.getPayload(), len, &rpos); cJSON* tmpArray = cJSON_CreateArray(), * tmpArray2 = cJSON_CreateArray(); for (int c = 0; c < len; ++c) { ReadT(msg.getPayload(), d, &rpos); cJSON_AddItemToArray(tmpArray, cJSON_CreateString(d)); cJSON_AddItemToArray(tmpArray2, cJSON_CreateString(d)); } if (!t_isRepeat) cJSON_AddItemToObject(ret, i->mName.c_str(), tmpArray); cJSON_AddItemToObject(extendJs.get(), i->mName.c_str(), tmpArray2); } else if (i->mType == "array_wstring") { int len = 0; CSimpleStringW d = ""; ReadT(msg.getPayload(), len, &rpos); cJSON* tmpArray = cJSON_CreateArray(), * tmpArray2 = cJSON_CreateArray(); for (int c = 0; c < len; ++c) { ReadT(msg.getPayload(), d, &rpos); cJSON_AddItemToArray(tmpArray, cJSON_CreateString(CSimpleStringW2A(d))); cJSON_AddItemToArray(tmpArray2, cJSON_CreateString(CSimpleStringW2A(d))); } if (!t_isRepeat) cJSON_AddItemToObject(ret, i->mName.c_str(), tmpArray); cJSON_AddItemToObject(extendJs.get(), i->mName.c_str(), tmpArray2); } else if (i->mType == "array_blob") { int array_size = 0; ReadT(msg.getPayload(), array_size, &rpos);//array size //DbgEx("array_blob 1:%d", msg.getBufferLength()); //msg.hexToFile(); cJSON* tmpArray = cJSON_CreateArray(), * tmpArray2 = cJSON_CreateArray(); for (int c = 0; c < array_size; ++c) { int tmpSize = 0; ReadT(msg.getPayload(), tmpSize, &rpos); if (0 != tmpSize) { void* binData = (char*)malloc(sizeof(char) * tmpSize); ReadT(msg.getPayload(), binData, tmpSize, &rpos); //DbgEx("array_blob 2:%d", tmpSize); int base64Len = modp_b64_encode_len(tmpSize); char* base64Data = (char*)malloc(sizeof(char) * base64Len); modp_b64_encode(base64Data, (const char*)binData, tmpSize); cJSON_AddItemToArray(tmpArray, cJSON_CreateString(base64Data)); cJSON_AddItemToArray(tmpArray2, cJSON_CreateString(base64Data)); } } if (!t_isRepeat) cJSON_AddItemToObject(ret, i->mName.c_str(), tmpArray); cJSON_AddItemToObject(extendJs.get(), i->mName.c_str(), tmpArray2); } else DbgEx("DeserializeBase error name -> type: %s -> %s", i->mName.c_str(), i->mType.c_str()); ++i; } } catch (...) { if (i != ts.mParamList.end()) DbgEx("DeserializeBase error:%s, %s", i->mName.c_str(), i->mType.c_str()); } char* unformateStr = cJSON_PrintUnformatted(extendJs.get()); std::string dstPayLoad = unformateStr; delete[]unformateStr; cJSON_AddStringToObject(ret, PARAMLIST_HEAD, dstPayLoad.c_str()); } void CWSCodec::DeserializeRequestAck(CMessage & msg, std::map::iterator & it, int& rpos, cJSON * ret) { entity_def_struct* p_struct = &it->second; CMedthodInterface* mi = mInterpreter->getFunctionInterface(p_struct->entity_name, p_struct->class_name, p_struct->methodID); CTransStruct ts = mi->mResponseInterpreter; try { DeserializeBase(msg, ts, rpos, ret); } catch (...) { DbgEx("error DeserializeRequestAck: %s, %s, %s", p_struct->entity_name, p_struct->class_name, p_struct->methodID); std::string errorMsg; #if (defined _WIN32 || defined _WIN64) for each (auto it in ts.mParamList) #else for (auto it : ts.mParamList) #endif errorMsg += it.mName + "--" + it.mType + "_"; DbgEx(errorMsg.c_str()); #if (defined _WIN32 || defined _WIN64) throw std::exception("error DeserializeRequestAck"); #else throw std::exception(std::logic_error("error DeserializeRequestAck")); #endif } } void CWSCodec::DeserializeEvent(CMessage & msg, std::vector*list, int& rpos, cJSON * ret) { int eventID = msg.getEventID(); if (NULL == list || eventID < 0 || eventID >= list->size()) { cJSON_AddNumberToObject(ret, "errorCode", Error_Unexpect); CSimpleStringA errmsg = ""; errmsg.Format("Cannot find the eventID = %d!", eventID); cJSON_AddStringToObject(ret, "errorMsg", errmsg); return; } CMedthodInterface* mi = &(list->at(eventID)); CTransStruct ts = mi->mResponseInterpreter; try { DeserializeBase(msg, ts, rpos, ret); } catch (...) { std::string errorMsg; #if (defined _WIN32 || defined _WIN64) for each (auto it in ts.mParamList) #else for (auto it : ts.mParamList) #endif errorMsg += it.mName + "--" + it.mType + "_"; DbgEx(errorMsg.c_str()); #if (defined _WIN32 || defined _WIN64) throw std::exception("error DeserializeRequestAck"); #else throw std::exception(std::logic_error("error DeserializeRequestAck")); #endif } } std::string CWSCodec::BufferToJson(CMessage & msg, boost::function dealErrcodeFun, int replaceTransId) { //replaceTransId==0,MessageType为8(Event),其他都应该有值 int rpos = 16; cJSON* ret = cJSON_CreateObject(); int errorCode = Error_Succeed; int userCode = 0; CSimpleStringA errorMsg = ""; //receivehexdump(msg.getPayload(), msg.getLength()); if (msg.getLength() < 12) //End session len = 12 return std::string(); // 丢弃消息 int srcTransId = msg.getTransID(); // 通用反序列化 cJSON_AddNumberToObject(ret, "messageType", msg.getMessageType()); switch (msg.getMessageType()) { case RequestAck: //PKT_TYPE_REQACK cJSON_AddNumberToObject(ret, "sessionID", msg.getSessionID()); cJSON_AddNumberToObject(ret, "transID", replaceTransId != 0 ? replaceTransId : msg.getTransID()); cJSON_AddNumberToObject(ret, "isEnd", msg.getIsEnd()); rpos += 1; #if (defined _WIN32 || defined _WIN64) #else ReadT(msg.getPayload(), userCode, &rpos); /** 业务端要求返回userCode,需要改动框架,依赖信创版本框架 1.0.7-dev15 [Gifur@2021119]*/ #endif ReadT(msg.getPayload(), errorCode, &rpos); cJSON_AddNumberToObject(ret, "errorCode", errorCode); ReadT(msg.getPayload(), errorMsg, &rpos); { auto userCodeInfo = splitStrToUserCodeAndErrMsg(errorMsg.GetData()); if (userCodeInfo.first != 0) cJSON_AddNumberToObject(ret, "userCode", userCodeInfo.first); cJSON_AddStringToObject(ret, "errorMsg", userCodeInfo.second.c_str()); } break; case SessionAck: cJSON_AddNumberToObject(ret, "sessionID", msg.getSessionID()); cJSON_AddNumberToObject(ret, "transID", replaceTransId != 0 ? replaceTransId : msg.getTransID()); ReadT(msg.getPayload(), errorCode, &rpos); cJSON_AddNumberToObject(ret, "errorCode", errorCode); ReadT(msg.getPayload(), errorMsg, &rpos); { auto userCodeInfo = splitStrToUserCodeAndErrMsg(errorMsg.GetData()); if (userCodeInfo.first != 0) cJSON_AddNumberToObject(ret, "userCode", userCodeInfo.first); cJSON_AddStringToObject(ret, "errorMsg", userCodeInfo.second.c_str()); } break; case Event: cJSON_AddNumberToObject(ret, "transID", replaceTransId != 0 ? replaceTransId : msg.getTransID()); cJSON_AddNumberToObject(ret, "eventID", msg.getEventID()); cJSON_AddNumberToObject(ret, "signatureID", msg.getSignatureID()); rpos += 8; break; case SetVarAck: cJSON_AddNumberToObject(ret, "sessionID", msg.getSessionID()); cJSON_AddNumberToObject(ret, "transID", replaceTransId != 0 ? replaceTransId : msg.getTransID()); ReadT(msg.getPayload(), errorCode, &rpos); cJSON_AddNumberToObject(ret, "errorCode", errorCode); ReadT(msg.getPayload(), errorMsg, &rpos); { auto userCodeInfo = splitStrToUserCodeAndErrMsg(errorMsg.GetData()); if (userCodeInfo.first != 0) cJSON_AddNumberToObject(ret, "userCode", userCodeInfo.first); cJSON_AddStringToObject(ret, "errorMsg", userCodeInfo.second.c_str()); } break; case GetVarAck: cJSON_AddNumberToObject(ret, "sessionID", msg.getSessionID()); cJSON_AddNumberToObject(ret, "transID", replaceTransId != 0 ? replaceTransId : msg.getTransID()); ReadT(msg.getPayload(), errorCode, &rpos); cJSON_AddNumberToObject(ret, "errorCode", errorCode); ReadT(msg.getPayload(), errorMsg, &rpos); cJSON_AddStringToObject(ret, "value", errorMsg); break; default: errorCode = Error_Unexpect; cJSON_AddNumberToObject(ret, "errorCode", errorCode); cJSON_AddStringToObject(ret, "errorMsg", "未知消息类型"); break; } DbgEx("BufferToJson -> messageType=%d(%s), sessionID=%d(%02X), transID=%d(%02X), replaceTransID=%d(%02X), errorCode=%d(%s)", msg.getMessageType(), GetMessageTypeString(msg.getMessageType()).c_str(), msg.getSessionID(), msg.getSessionID(), srcTransId, srcTransId, replaceTransId , replaceTransId, errorCode, SpStrError((ErrorCodeEnum)errorCode)); if (Error_Succeed != errorCode) dealErrcodeFun(errorCode, srcTransId); if(replaceTransId) msg.setTransID(replaceTransId); // RequestAck 返回的有问题 要删除对应的回调list项 if (Error_Succeed != errorCode && RequestAck == msg.getMessageType()) { std::map::iterator it = m_AckCallbackList.find(msg.getTransID()); if (m_AckCallbackList.end() != it) { m_ackMutex.lock(); m_AckCallbackList.erase(it); m_ackMutex.unlock(); } } // 有错误时直接返回 或者 不是RequestAck和Event时也可以返回 if (Error_Succeed != errorCode || (RequestAck != msg.getMessageType() && Event != msg.getMessageType())) { char* str = getJsonStr(ret); cJSON_Delete(ret); std::string s(str); free(str); return s; } // 数据部分反序列化 RequestAck & Event有数据部分 if (RequestAck == msg.getMessageType()) { // Request用户自定义部分反序列化 // 回调反序列化列表 m_ackMutex.lock(); std::shared_ptr delHandleFun((void*)0, [&](void*) { m_ackMutex.unlock(); }); std::map::iterator it = m_AckCallbackList.find(msg.getTransID()); if (m_AckCallbackList.end() == it) { // 没有对应的request,无法反序列化 cJSON_AddNumberToObject(ret, "errorCode", Error_Unexpect); cJSON_AddStringToObject(ret, "errorMsg", "Cannot find the request for the ack!"); char* str = getJsonStr(ret); cJSON_Delete(ret); std::string s(str); free(str); return s; } DeserializeRequestAck(msg, it, rpos, ret); m_AckCallbackList.erase(it); } else if (Event == msg.getMessageType()) { // Event用户自定义部分反序列化 std::map*>::iterator iter = m_EventCallbackList.find(msg.getTransID()); if (m_EventCallbackList.end() == iter) { // 没有对应的register, 无法反序列化 cJSON_AddNumberToObject(ret, "errorCode", Error_Unexpect); cJSON_AddStringToObject(ret, "errorMsg", "Cannot find the register for the ack!"); char* str = getJsonStr(ret); cJSON_Delete(ret); std::string s(str); free(str); return s; } DeserializeEvent(msg, iter->second, rpos, ret); } char* str = getJsonStr(ret); cJSON_Delete(ret); std::string s(str); free(str); //delete []str; return s; } std::pair CWSCodec::JsonToBuffer(std::string strJson) { //int pos = strJson.find('}'); //try to test json with linkInfo //strJson = strJson.substr(0, pos) + ",\"BussinessId\":\"DoInit\",\"TraceId\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\"SpanId\":\"AAAAAAAAAAAAAAAA\",\"ParentSpanId\":\"AAAAAAAAAAAAAAAA\",\"Timestamp\":\"\",\"ReservedControl\":0}"; cJSON* pJson = cJSON_Parse(strJson.c_str()); char errmsg[1024] = { 0 }; unsigned int messageType = 0; GetCJsonIntergerValue(pJson, "messageType", messageType, errmsg); // 查找序列化结构 有用户定义数据部分的只有 Info 和 Request CMedthodInterface* mi = NULL; if (Request == messageType || Info == messageType) { entity_def_struct st = { 0 }; GetCJsonObjectValue(pJson, "class", st.class_name, errmsg); GetCJsonObjectValue(pJson, "entity", st.entity_name, errmsg); GetCJsonIntergerValue(pJson, "methodID", st.methodID, errmsg); mi = mInterpreter->getFunctionInterface(st.entity_name, st.class_name, st.methodID); //get the mothod of the json if (NULL == mi) { DbgEx("JsonToBuffer : Entity or class not found in structure interpreter! entityName:%s, class_name:%s, methodId:%d", st.entity_name, st.class_name, st.methodID); return std::make_pair(messageType, nullptr); } else DbgEx("JsonToBuffer parse method success, entityName:%s, className:%s, methodID:%d, DstMethodName:%s, DstMethodParamNum:%d", st.entity_name, st.class_name, st.methodID, mi->mMethodName.c_str(), mi->mRequestInterpreter.mParamList.size()); //如出错,可对比方法名和变量数量 if (Request == messageType) { // 维护回调列表 Request auto transid = json_deal::getIntergerFromCjsonObj(pJson, "transId"); if (transid.first == false) { DbgEx("CWSCodec::JsonToBuffer get transId failed"); return std::make_pair(messageType, nullptr); } m_ackMutex.lock(); m_AckCallbackList.insert(std::pair(transid.second, st)); m_ackMutex.unlock(); } } else if (Register == messageType) { std::vector* milist = NULL; entity_def_struct st = { 0 }; auto transid = json_deal::getIntergerFromCjsonObj(pJson, "transId"); if (transid.first == false) { DbgEx("CWSCodec::JsonToBuffer get transId failed"); return std::make_pair(messageType, nullptr); } GetCJsonObjectValue(pJson, "entity", st.entity_name, errmsg); milist = mInterpreter->getAllMessageInterface(st.entity_name); m_EventCallbackList.insert(std::pair*>(transid.second, milist)); } else if (Broadcast == messageType) { ChromiumBroadcast e = {}; GetCJsonObjectValue(pJson, "data", e.broadcastJson, errmsg); if (e.broadcastJson.GetLength() < 20000) { auto rc = SpSendBroadcast(m_pFunc, eMsg_ChromiumBroadcast, eMsgSig_ChromiumBroadcast, e); if (Error_Succeed != rc) DbgEx("Broadcast Msg Error:%d", rc); } else DbgEx("json is too long, do not send out sp broadcast!"); return std::make_pair(messageType, nullptr); } else if (Event == messageType) {// 维护回调列表 Event struct GeneralEventStruct { CSimpleStringA data; void Serialize(SpBuffer& Buf) { auto& buf = Buf & data; } }; struct GeneralEventStruct e = {}; unsigned int eventID = 0; unsigned int eventSign = 0; GetCJsonIntergerValue(pJson, "eventID", eventID, errmsg); GetCJsonIntergerValue(pJson, "eventSign", eventSign, errmsg); GetCJsonObjectValue(pJson, "data", e.data, errmsg); SpSendBroadcast(m_pFunc, eventID, eventSign, e); //if (0 < strlen(errmsg)) // DbgEx("JsonToBuffer errmsg : %s", errmsg); cJSON_Delete(pJson); return std::make_pair(messageType, nullptr); } // 数据定义 char* data = (char*)malloc(MAX_TRANSFER_LEN); assert(data != NULL); int capacity = MAX_TRANSFER_LEN; int wpos = 0; unsigned int len = 0; // 通用序列化 // 预先写入长度0 WriteT(data, len, &wpos, &capacity); //写入messageType,附带链路信息 int messageTypeWithControl = messageType | PKT_TYPE_CONTROL_LINKCONTEXT; WriteT(data, messageTypeWithControl, &wpos, &capacity); // 根据不同的request进行序列化 switch (messageType) { //info和request由于有其他信息,需要在数据中获得context case Info: SerializeInfo(pJson, data, &wpos, &capacity, mi, errmsg); break; case Request: SerializeRequest(pJson, data, &wpos, &capacity, mi, errmsg); break; case BeginSession: SerializeBeginSession(pJson, data, &wpos, &capacity, mi, errmsg); SerializeLinkInfo(pJson, data, &wpos, &capacity, errmsg); break; case EndSession: SerializeEndSession(pJson, data, &wpos, &capacity, mi, errmsg); SerializeLinkInfo(pJson, data, &wpos, &capacity, errmsg); break; case Register: SerializeRegister(pJson, data, &wpos, &capacity, mi, errmsg); SerializeLinkInfo(pJson, data, &wpos, &capacity, errmsg); break; case Unregister: SerializeUnregister(pJson, data, &wpos, &capacity, mi, errmsg); SerializeLinkInfo(pJson, data, &wpos, &capacity, errmsg); break; case LogEventMsgType: SerializeLogEvent(pJson, data, &wpos, &capacity, mi, errmsg); SerializeLinkInfo(pJson, data, &wpos, &capacity, errmsg); break; case LogWarnMsgType: SerializeLogWarn(pJson, data, &wpos, &capacity, mi, errmsg); SerializeLinkInfo(pJson, data, &wpos, &capacity, errmsg); break; case SetVarReq: SerializeSetVarReq(pJson, data, &wpos, &capacity, mi, errmsg); SerializeLinkInfo(pJson, data, &wpos, &capacity, errmsg); break; case GetVarReq: SerializeGetVarReq(pJson, data, &wpos, &capacity, mi, errmsg); SerializeLinkInfo(pJson, data, &wpos, &capacity, errmsg); break; default: // warn break; }; // 修改头部的消息长度 int i = 0; len = wpos - 8; WriteT(data, len, &i, &capacity); //if (0 < strlen(errmsg)) // DbgEx("JsonToBuffer errmsg : %s, len = %d", errmsg, len); cJSON_Delete(pJson); if (wpos < m_SerializeCache.getCMessageLength()) { m_SerializeCache.clear(); if (nullptr == memcpy(m_SerializeCache.getWriteableData(), data, wpos)) DbgEx("memcpy err "); free(data); } else { //数据长度过长 free(data); DbgEx("string too long, discard"); return std::make_pair(messageType, nullptr); } return std::make_pair(messageType, &m_SerializeCache); } char* CWSCodec::getJsonStr(cJSON * pJson) { char* pStr = cJSON_PrintUnformatted(pJson); if (NULL == pStr) { pStr = (char*)malloc(64); if (pStr) { strncpy(pStr, "{\"errorCode\":1540,\"errormsg\":\"Failed to encode json\"}", 64); } } return pStr; } void CWSCodec::SerializeLinkInfo(cJSON* js, char* data, int* wpos, int* capacity, char* errmsg) { auto linkContextRet = GetLinkContex(js, data, errmsg); if (linkContextRet.first) { linkContext curLink; curLink.bussinessId = std::get<0>(linkContextRet.second); curLink.traceId = std::get<1>(linkContextRet.second); curLink.spanId = std::get<2>(linkContextRet.second); curLink.parentSpanId = std::get<3>(linkContextRet.second); DbgToBeidou(curLink, __FUNCTION__)(); //chromium节点 auto newLink = curLink.upgradeLink(); WriteT(data, newLink.bussinessId, wpos, capacity); WriteT(data, newLink.traceId, wpos, capacity); WriteT(data, newLink.spanId, wpos, capacity); WriteT(data, newLink.parentSpanId, wpos, capacity); //DbgToBeidou(newLink, __FUNCTION__)(); } else// 生成链路信息 { linkContext curLink; curLink.bussinessId = "ChromiumAutoGen"; curLink.traceId = uuid4_generate(32).c_str(); curLink.spanId = uuid4_generate(16).c_str(); curLink.parentSpanId = "0"; DbgToBeidou(curLink, __FUNCTION__)(); auto newLink = curLink.upgradeLink(); WriteT(data, newLink.bussinessId, wpos, capacity);//为适配silverlight,默认写入就是unicode WriteT(data, newLink.traceId, wpos, capacity); WriteT(data, newLink.spanId, wpos, capacity); WriteT(data, newLink.parentSpanId, wpos, capacity); //DbgToBeidou(curLink, __FUNCTION__)(); } } void CWSCodec::SerializeInfo(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { auto sessionID = json_deal::getIntergerFromCjsonObj(js, "sessionID"); if (sessionID.first == false) { DbgEx("CWSCodec::SerializeInfo get sessionId failed"); return; } auto methodID = json_deal::getIntergerFromCjsonObj(js, "methodID"); if (methodID.first == false) { DbgEx("CWSCodec::SerializeInfo get methodID failed"); return; } auto signature = json_deal::getIntergerFromCjsonObj(js, "signature"); if (signature.first == false) { DbgEx("CWSCodec::SerializeInfo get signature failed"); return; } WriteT(data, sessionID.second, wpos, capacity); WriteT(data, methodID.second, wpos, capacity); WriteT(data, signature.second, wpos, capacity); SerializeLinkInfo(js, data, wpos, capacity, errmsg); if (NULL == pI) { DbgEx("PI = NULL, 无法找到接口定义"); return;// 没有对应定义 } auto paramJs = cJSON_GetObjectItem(js, PARAMLIST_HEAD);//不更换,因为不为获取值 if (paramJs == NULL) { //detect the same name std::string t_arr[] = { "transID", "sessionID", "methodID", "signature", "timeout" ,"messageType","class","entity","methodID" }; std::vector c_repeatParamList(t_arr, t_arr + sizeof(t_arr) / sizeof(t_arr[0])); #if (defined _WIN32 || defined _WIN64) for each (auto paramInfo in pI->mRequestInterpreter.mParamList) { for each (auto repeatName in c_repeatParamList) { #else for (auto paramInfo : pI->mRequestInterpreter.mParamList) { for (auto repeatName : c_repeatParamList) { #endif if (paramInfo.mName == repeatName) DbgEx("request参数名字重复, error, %s", paramInfo.mName.c_str()); } } //如果存在重复,可能数据已经脏了,所以也不需要作删除参数处理 paramJs = js; } GeneralSerialize(paramJs, data, wpos, capacity, pI, errmsg); return; } std::pair> CWSCodec::GetLinkContex(cJSON * js, char* data, char* errmsg) { /* typedef struct { char businessId[32]; //32 char traceId[32]; //32 char spanId[16]; //16 char parentSpanId[16]; //16 char timestamp[16]; //16 int reservedControl; }link_context; */ CSimpleStringA BussinessId, TraceId, SpanId, ParentSpanId, Timestamp; int ReservedControl; GetCJsonObjectValue(js, "BusinessId", BussinessId, errmsg); GetCJsonObjectValue(js, "TraceId", TraceId, errmsg); GetCJsonObjectValue(js, "SpanId", SpanId, errmsg); GetCJsonObjectValue(js, "ParentSpanId", ParentSpanId, errmsg); GetCJsonObjectValue(js, "Timestamp", Timestamp, errmsg); GetCJsonIntergerValue(js, "ReservedControl", ReservedControl, errmsg); if (BussinessId.GetLength() > 0 && BussinessId.GetLength() < 32 && TraceId.GetLength() == 32 && SpanId.GetLength() == 16) return std::make_pair(true, std::make_tuple(BussinessId, TraceId, SpanId, ParentSpanId, Timestamp, ReservedControl)); else return std::make_pair(false, std::make_tuple("", "", "", "", "", 0)); } void CWSCodec::SerializeBeginSession(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { int i4 = 0; GetCJsonIntergerValue(js, "transID", i4, errmsg); WriteT(data, i4, wpos, capacity); CSimpleStringA s = ""; GetCJsonObjectValue(js, "entity", s, errmsg); WriteT(data, s, wpos, capacity); GetCJsonObjectValue(js, "method", s, errmsg); WriteT(data, s, wpos, capacity); GetCJsonObjectValue(js, "class", s, errmsg); WriteT(data, s, wpos, capacity); } void CWSCodec::SerializeEndSession(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { auto sessionID = json_deal::getIntergerFromCjsonObj(js, "sessionID"); if (sessionID.first == false) { DbgEx("CWSCodec::SerializeEndSession get sessionId failed"); return; } WriteT(data, sessionID.second, wpos, capacity); } void CWSCodec::SerializeRequest(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { auto transID = json_deal::getIntergerFromCjsonObj(js, "transID"); if (transID.first == false) { DbgEx("CWSCodec::SerializeRequest get transID failed"); return; } auto sessionID = json_deal::getIntergerFromCjsonObj(js, "sessionID"); if (sessionID.first == false) { DbgEx("CWSCodec::SerializeRequest get sessionID failed"); return; } auto methodID = json_deal::getIntergerFromCjsonObj(js, "methodID"); if (methodID.first == false) { DbgEx("CWSCodec::SerializeRequest get methodID failed"); return; } auto signature = json_deal::getIntergerFromCjsonObj(js, "signature"); if (signature.first == false) { DbgEx("CWSCodec::SerializeRequest get signature failed"); return; } auto timeout = json_deal::getIntergerFromCjsonObj(js, "timeout"); if (timeout.first == false) { DbgEx("CWSCodec::SerializeRequest get timeout failed"); return; } WriteT(data, transID.second, wpos, capacity); WriteT(data, sessionID.second, wpos, capacity); WriteT(data, methodID.second, wpos, capacity); WriteT(data, signature.second, wpos, capacity); WriteT(data, timeout.second, wpos, capacity); SerializeLinkInfo(js, data, wpos, capacity, errmsg); if (NULL == pI) { // 没有对应定义 DbgEx("没有对应定义"); return; } auto paramJs = cJSON_GetObjectItem(js, PARAMLIST_HEAD);//不改动,因为不是为了获取值 if (paramJs == NULL) { //detect the same name std::string t_arr[] = { "transID", "sessionID", "methodID", "signature", "timeout" ,"messageType","class","entity","methodID" }; std::vector c_repeatParamList(t_arr, t_arr + sizeof(t_arr) / sizeof(t_arr[0])); #if (defined _WIN32 || defined _WIN64) for each (auto paramInfo in pI->mRequestInterpreter.mParamList) { for each (auto repeatName in c_repeatParamList) { #else for (auto paramInfo : pI->mRequestInterpreter.mParamList) { for (auto repeatName : c_repeatParamList) { #endif if (paramInfo.mName == repeatName) DbgEx("request参数名字重复, error, %s", paramInfo.mName.c_str()); } } //如果存在重复,可能数据已经脏了,所以也不需要作删除参数处理 paramJs = js; } GeneralSerialize(paramJs, data, wpos, capacity, pI, errmsg); } void CWSCodec::SerializeRegister(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { auto transID = json_deal::getIntergerFromCjsonObj(js, "transID"); if (transID.first == false) { DbgEx("CWSCodec::SerializeRegister get transID failed"); return; } auto entity = json_deal::getStringFromCjsonObj(js, "entity"); if (entity.first == false) { DbgEx("CWSCodec::SerializeRegister get entity failed"); return; } WriteT(data, transID.second, wpos, capacity); WriteT(data, entity.second, wpos, capacity); CSimpleStringA tmp = ""; WriteT(data, tmp, wpos, capacity);//订阅实体全局,不限定方法 } void CWSCodec::SerializeUnregister(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { auto transID = json_deal::getIntergerFromCjsonObj(js, "transID"); if (transID.first == false) { DbgEx("CWSCodec::SerializeUnregister get transID failed"); return; } WriteT(data, transID.second, wpos, capacity); } void CWSCodec::SerializeLogEvent(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { auto securityLevel = json_deal::getIntergerFromCjsonObj(js, "securityLevel"); if (securityLevel.first == false) { DbgEx("CWSCodec::SerializeUnregister get securityLevel failed"); return; } auto eventCode = json_deal::getIntergerFromCjsonObj(js, "eventCode"); if (eventCode.first == false) { DbgEx("CWSCodec::SerializeUnregister get eventCode failed"); return; } auto message = json_deal::getStringFromCjsonObj(js, "message"); if (message.first == false) { DbgEx("CWSCodec::SerializeUnregister get message failed"); return; } WriteT(data, securityLevel.second, wpos, capacity); WriteT(data, eventCode.second, wpos, capacity); WriteT(data, message.second, wpos, capacity); } inline CSimpleStringA DWORD2Hex(DWORD cur) { return CSimpleStringA::Format("%X", cur); } void CWSCodec::SerializeLogWarn(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { auto securityLevel = json_deal::getIntergerFromCjsonObj(js, "securityLevel"); if (securityLevel.first == false) { DbgEx("CWSCodec::SerializeLogWarn get securityLevel failed"); return; } auto eventCode = json_deal::getIntergerFromCjsonObj(js, "eventCode"); if (eventCode.first == false) { DbgEx("CWSCodec::SerializeLogWarn get eventCode failed"); return; } auto message = json_deal::getStringFromCjsonObj(js, "message"); if (message.first == false) { DbgEx("CWSCodec::SerializeLogWarn get message failed"); return; } WriteT(data, securityLevel.second, wpos, capacity); WriteT(data, eventCode.second, wpos, capacity); WriteT(data, message.second, wpos, capacity); DbgWithLink(securityLevel.second == SeverityLevelEnum::Severity_Low ? LOG_LEVEL_INFO : LOG_LEVEL_WARN, LOG_TYPE_SYSTEM) .setResultCode(DWORD2Hex(eventCode.second).GetData()) ("receive warn from web, Warn: {%s}(sc=0x%X, uc=0x%X)", message.second.GetData(), 0, eventCode.second); } void CWSCodec::SerializeSetVarReq(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { auto transID = json_deal::getIntergerFromCjsonObj(js, "transID"); if (transID.first == false) { DbgEx("CWSCodec::SerializeSetVarReq get transID failed"); return; } auto name = json_deal::getStringFromCjsonObj(js, "name"); if (name.first == false) { DbgEx("CWSCodec::SerializeSetVarReq get name failed"); return; } auto value = json_deal::getStringFromCjsonObj(js, "value"); if (value.first == false) { DbgEx("CWSCodec::SerializeSetVarReq get value failed"); return; } WriteT(data, transID.second, wpos, capacity); WriteT(data, name.second, wpos, capacity); WriteT(data, value.second, wpos, capacity); } using namespace std; vector split(const string & s, const string & seperator) { vector result; typedef string::size_type string_size; string_size i = 0; while (i != s.size()) { //找到字符串中首个不等于分隔符的字母; int flag = 0; while (i != s.size() && flag == 0) { flag = 1; for (string_size x = 0; x < seperator.size(); ++x) if (s[i] == seperator[x]) { ++i; flag = 0; break; } } //找到又一个分隔符,将两个分隔符之间的字符串取出; flag = 0; string_size j = i; while (j != s.size() && flag == 0) { for (string_size x = 0; x < seperator.size(); ++x) if (s[j] == seperator[x]) { flag = 1; break; } if (flag == 0) ++j; } if (i != j) { result.emplace_back(s.substr(i, j - i)); i = j; } } return result; } void CWSCodec::SerializeGetVarReq(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { auto transID = json_deal::getIntergerFromCjsonObj(js, "transID"); if (transID.first == false) { DbgEx("CWSCodec::SerializeGetVarReq get transID failed"); return; } auto name = json_deal::getStringFromCjsonObj(js, "name"); if (name.first == false) { DbgEx("CWSCodec::SerializeGetVarReq get name failed"); return; } WriteT(data, transID.second, wpos, capacity); WriteT(data, name.second, wpos, capacity); } void CWSCodec::GeneralSerialize(cJSON * js, char* data, int* wpos, int* capacity, CMedthodInterface * pI, char* errmsg) { std::list::iterator it = pI->mRequestInterpreter.mParamList.begin(); auto dealBlob = [](CSimpleString src, char* bin)->std::pair { if (!is_base64(src)) return std::make_pair(-1, "base64 decode failed!"); int binlen = modp_b64_decode_len(src.GetLength()) - 1;//二进制流,不需要结束 if (binlen > 0) { bin = new char[binlen + 1]; ZeroMemory(bin, binlen + 1); modp_b64_decode(bin, src.GetData(), src.GetLength());//binlen有可能比bin长 short objectNum = *((short*)bin); int extendLen = 2 + objectNum * 2; int dstLen = binlen - (binlen - extendLen) % 4; return std::make_pair(dstLen, ""); } else return std::make_pair(-1, "error binlen"); }; while (it != pI->mRequestInterpreter.mParamList.end()) { if (it->mType == "int") { unsigned int d = 0; GetCJsonIntergerValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "bool") { bool d = true; GetCJsonIntergerValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "double") { double d = 0; GetCJsonObjectValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "char") { char d = 0; GetCJsonIntergerValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "short") { short d = 0; GetCJsonIntergerValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "ushort") { unsigned short d = 0; GetCJsonIntergerValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "uint") { unsigned int d = 0; GetCJsonIntergerValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "int64") { __int64 d = 0; GetCJsonIntergerValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "uint64") { #if (defined _WIN32 || defined _WIN64) unsigned __int64 d = 0; #else u_int64_t d = 0; #endif GetCJsonIntergerValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "uchar") { unsigned char d = 0; GetCJsonIntergerValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "string") { CSimpleStringA d = ""; GetCJsonObjectValue(js, it->mName.c_str(), d, errmsg); //DbgEx("GeneralSerialize string %s -> %s", it->mName.c_str(), d); WriteT(data, d, wpos, capacity); } else if (it->mType == "wstring") { CSimpleStringW d = ""; GetCJsonObjectValue(js, it->mName.c_str(), d, errmsg); WriteT(data, d, wpos, capacity); } else if (it->mType == "blob") { CSimpleStringA d = ""; GetCJsonObjectValue(js, it->mName.c_str(), d, errmsg); if (!is_base64(d)) { strcat(errmsg, "base64 decode failed!"); ++it; continue; } int binlen = modp_b64_decode_len(d.GetLength()) - 1;//二进制流,不需要结束 char* bin = NULL; if (binlen > 0) { bin = new char[binlen + 1]; ZeroMemory(bin, binlen + 1); modp_b64_decode(bin, d.GetData(), d.GetLength());//binlen有可能比bin长 short objectNum = *((short*)bin); int extendLen = 2 + objectNum * 2; int dstLen = binlen - (binlen - extendLen) % 4; std::string tempBlob = "blob len , " + std::to_string((ULONGLONG)dstLen) + ":"; for (size_t i = 0; i < dstLen; i++) tempBlob += std::to_string((ULONGLONG)(unsigned char)bin[i]) + ","; DbgEx(tempBlob.c_str()); WriteT(data, dstLen, wpos, capacity); WriteT(data, bin, wpos, capacity, dstLen); delete[]bin; bin = NULL; } } else if (it->mType == "array_int") { //DbgEx("array int -> "); int len = 0; if (GetCJsonArraySize(js, it->mName.c_str(), len, errmsg)) { //DbgEx("array int -> true len = %d", len); WriteT(data, len, wpos, capacity); unsigned int d = 0; for (int i = 0; i < len; ++i) { if (!GetCJsonObjectValue(cJSON_GetArrayItem(cJSON_GetObjectItem(js, it->mName.c_str()), i), d, errmsg)) break; WriteT(data, d, wpos, capacity); } } else { DbgEx("array int -> false len = %d", len); WriteT(data, len, wpos, capacity); } } else if (it->mType == "array_bool") { int len = 0; if (GetCJsonArraySize(js, it->mName.c_str(), len, errmsg)) { WriteT(data, len, wpos, capacity); unsigned int d = 0; bool dst = false; for (int i = 0; i < len; ++i) { if (!GetCJsonObjectValue(cJSON_GetArrayItem(cJSON_GetObjectItem(js, it->mName.c_str()), i), d, errmsg)) break; dst = d; WriteT(data, dst, wpos, capacity); } } else { DbgEx("array bool -> false len = %d", len); WriteT(data, len, wpos, capacity); } } else if (it->mType == "array_uint") { //DbgEx("array uint -> "); int len = 0; if (GetCJsonArraySize(js, it->mName.c_str(), len, errmsg)) { //DbgEx("array int -> true len = %d", len); WriteT(data, len, wpos, capacity); unsigned int d = 0; for (int i = 0; i < len; ++i) { if (!GetCJsonObjectValue(cJSON_GetArrayItem(cJSON_GetObjectItem(js, it->mName.c_str()), i), d, errmsg)) { DbgEx("[%d] failed %s, break", i, errmsg); break; } WriteT(data, d, wpos, capacity); } } else { DbgEx("array int -> false len = %d", len); WriteT(data, len, wpos, capacity); } } else if (it->mType == "array_string") { //DbgEx("array string -> "); int len = 0; if (GetCJsonArraySize(js, it->mName.c_str(), len, errmsg)) { //DbgEx("array string -> true len = %d", len); WriteT(data, len, wpos, capacity); CSimpleStringA d = ""; for (int i = 0; i < len; ++i) { if (!GetCJsonObjectValue(cJSON_GetArrayItem(cJSON_GetObjectItem(js, it->mName.c_str()), i), d, errmsg)) { DbgEx("array string[%d] failed %s, break", i, errmsg); break; } WriteT(data, d, wpos, capacity); } } else { DbgEx("array string -> false len = %d", len); WriteT(data, len, wpos, capacity); } } else if (it->mType == "array_wstring") { int len = 0; if (GetCJsonArraySize(js, it->mName.c_str(), len, errmsg)) { WriteT(data, len, wpos, capacity); CSimpleStringW d = ""; for (int i = 0; i < len; ++i) { if (!GetCJsonObjectValue(cJSON_GetArrayItem(cJSON_GetObjectItem(js, it->mName.c_str()), i), d, errmsg)) { DbgEx("[%d] failed %s, break", i, errmsg); break; } WriteT(data, d, wpos, capacity); } } else { WriteT(data, len, wpos, capacity); } } else if (it->mType == "array_blob") { int len = 0; if (GetCJsonArraySize(js, it->mName.c_str(), len, errmsg)) { WriteT(data, len, wpos, capacity); CSimpleStringW d = ""; for (int i = 0; i < len; ++i) { if (!GetCJsonObjectValue(cJSON_GetArrayItem(cJSON_GetObjectItem(js, it->mName.c_str()), i), d, errmsg)) { DbgEx("[%d] failed %s, break", i, errmsg); break; } WriteT(data, d, wpos, capacity); } } else { WriteT(data, len, wpos, capacity); } } else { DbgEx("GeneralSerialize error name -> type: %s -> %s", it->mName.c_str(), it->mType.c_str()); } ++it; } } bool CWSCodec::GetCJsonObjectValue(cJSON * root, const char* strKey, char* dstValue, char* errmsg) { cJSON* pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if (NULL != pTmpNode) { #if (defined _WIN32 || defined _WIN64) strncpy(dstValue, pTmpNode->valuestring, strlen(pTmpNode->valuestring)); #else strncpy(dstValue, pTmpNode->valuestring, strlen(pTmpNode->valuestring) + 1); #endif ret = true; } else { if (nullptr != errmsg) { strcat(errmsg, "-"); strcat(errmsg, strKey); } strncpy(dstValue, "", strlen("")); ret = false; } return ret; } bool CWSCodec::GetCJsonObjectValue(cJSON * root, const char* strKey, CSimpleStringA & dstValue, char* errmsg) { cJSON* pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if (NULL != pTmpNode) { #if (defined _WIN32 || defined _WIN64) dstValue = pTmpNode->valuestring; #else CSimpleStringW wStr = ""; UTF8ToUnicode(pTmpNode->valuestring, wStr); dstValue = CSimpleStringW2A(wStr); #endif ret = true; } else { if (nullptr != errmsg) { strcat(errmsg, "-"); strcat(errmsg, strKey); } dstValue = ""; ret = false; } return ret; } bool CWSCodec::GetCJsonObjectValue(cJSON * root, const char* strKey, std::string & dstValue, char* errmsg) { cJSON* pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if (NULL != pTmpNode) { #if (defined _WIN32 || defined _WIN64) dstValue = pTmpNode->valuestring; #else CSimpleStringW wStr = ""; UTF8ToUnicode(pTmpNode->valuestring, wStr); dstValue = CSimpleStringW2A(wStr); #endif ret = true; } else { if (nullptr != errmsg) { strcat(errmsg, "-"); strcat(errmsg, strKey); } dstValue = ""; ret = false; } return ret; } bool CWSCodec::GetCJsonObjectValue(cJSON * root, const char* strKey, CSimpleStringW & dstValue, char* errmsg) { cJSON* pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if (NULL != pTmpNode) { #if (defined _WIN32 || defined _WIN64) dstValue = CSimpleStringA2W(pTmpNode->valuestring); #else UTF8ToUnicode(pTmpNode->valuestring, dstValue); #endif ret = true; } else { if (nullptr != errmsg) { strcat(errmsg, "-"); strcat(errmsg, strKey); } dstValue = ""; ret = false; } return ret; } /* bool CWSCodec::GetCJsonObjectValue(cJSON *root, const char* strKey, unsigned int& dstValue, char* errmsg){ cJSON *pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if(NULL != pTmpNode){ dstValue = *(unsigned int*)&pTmpNode->valueint; ret = true; }else{ if(nullptr != errmsg) strcat(errmsg, strKey); dstValue = 0; ret = false; } return ret; } bool CWSCodec::GetCJsonObjectValue(cJSON *root, const char* strKey, unsigned short& dstValue, char* errmsg){ cJSON *pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if(NULL != pTmpNode){ dstValue = pTmpNode->valueint; ret = true; }else{ if(nullptr != errmsg) strcat(errmsg, strKey); dstValue = 0; ret = false; } return ret; } bool CWSCodec::GetCJsonObjectValue(cJSON *root, const char* strKey, short& dstValue, char* errmsg){ cJSON *pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if(NULL != pTmpNode){ dstValue = pTmpNode->valueint; ret = true; }else{ if(nullptr != errmsg) strcat(errmsg, strKey); dstValue = 0; ret = false; } return ret; } bool CWSCodec::GetCJsonObjectValue(cJSON *root, const char* strKey, int& dstValue, char* errmsg){ cJSON *pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if(NULL != pTmpNode){ dstValue = pTmpNode->valueint; ret = true; }else{ if(nullptr != errmsg) strcat(errmsg, strKey); dstValue = 0; ret = false; } return ret; } */ bool CWSCodec::GetCJsonObjectValue(cJSON * root, const char* strKey, double& dstValue, char* errmsg) { cJSON* pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if (NULL != pTmpNode) { dstValue = pTmpNode->valuedouble; ret = true; } else { if (nullptr != errmsg) { strcat(errmsg, "-"); strcat(errmsg, strKey); } dstValue = 0; ret = false; } return ret; } template bool CWSCodec::GetCJsonIntergerValue(cJSON * root, const char* strKey, T & dstValue, char* errmsg) { cJSON* pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if (NULL != pTmpNode) { dstValue = pTmpNode->valueint; ret = true; } else { if (nullptr != errmsg) { strcat(errmsg, "-"); strcat(errmsg, strKey); } dstValue = 0; ret = false; } return ret; } /* bool CWSCodec::GetCJsonObjectValue(cJSON *root, const char* strKey, bool& dstValue, char* errmsg){ cJSON *pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if(NULL != pTmpNode){ dstValue = pTmpNode->valueint; ret = true; }else{ if(nullptr != errmsg) strcat(errmsg, strKey); dstValue = 0; ret = false; } return ret; } */ bool CWSCodec::GetCJsonArraySize(cJSON * root, const char* strKey, int& dstValue, char* errmsg) { cJSON* pTmpNode = NULL; bool ret = false; pTmpNode = cJSON_GetObjectItem(root, strKey); if (NULL != pTmpNode) { dstValue = cJSON_GetArraySize(pTmpNode); ret = true; } else { if (nullptr != errmsg) { strcat(errmsg, "-"); strcat(errmsg, strKey); } dstValue = 0; ret = false; } return ret; } bool CWSCodec::GetCJsonObjectValue(cJSON * obj, int& dstValue, char* errmsg) { if (cJSON_Number == obj->type) { dstValue = obj->valueint; return true; } strcat(errmsg, "array member "); dstValue = 0; return false; } bool CWSCodec::GetCJsonObjectValue(cJSON * obj, unsigned int& dstValue, char* errmsg) { if (cJSON_Number == obj->type) { dstValue = obj->valueint; return true; } strcat(errmsg, "array member "); dstValue = 0; return false; } bool CWSCodec::GetCJsonObjectValue(cJSON * obj, CSimpleStringA & dstValue, char* errmsg) { if (cJSON_String == obj->type) { //DbgEx("GetCJsonObjectValue CSimpleStringA = %s", obj->valuestring); //hexdump(obj->valuestring, strlen(obj->valuestring)); #if (defined _WIN32 || defined _WIN64) dstValue = obj->valuestring; #else CSimpleStringW strw = ""; UTF8ToUnicode(obj->valuestring, strw); dstValue = CSimpleStringW2A(strw); #endif return true; } strcat(errmsg, "array member "); dstValue = ""; return false; } bool CWSCodec::GetCJsonObjectValue(cJSON * obj, CSimpleStringW & dstValue, char* errmsg) { if (cJSON_String == obj->type) { #if (defined _WIN32 || defined _WIN64) dstValue = CSimpleStringA2W(obj->valuestring); #else UTF8ToUnicode(obj->valuestring, dstValue); #endif return true; } strcat(errmsg, "array member "); dstValue = ""; return false; } int CWSCodec::UTF8ToUnicode(char* input, CSimpleStringW & output) { if (nullptr == input) return -1; #if (defined(_WIN32) || defined(_WIN64)) //UTF8 to Unicode //预转换,得到所需空间的大小 int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, input, strlen(input), NULL, 0); //分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间 wchar_t* wszString = new wchar_t[wcsLen + 1]; //转换 ::MultiByteToWideChar(CP_UTF8, NULL, input, strlen(input), wszString, wcsLen); //最后加上'\0' wszString[wcsLen] = '\0'; output = wszString; delete[] wszString; wszString = NULL; return 0; #else std::wstring ret = SP::Utility::S2W(input); output = ret.c_str(); return 0; #endif } void CWSCodec::hexdump(const char* buf, const int num) { char str[8192] = { 0 }; int i = 0; char c[5] = { 0 }; if (num > 100) { for (i = 0; i < 50; i++) { sprintf(c, "%02X ", (unsigned char)buf[i]); strcat(str, c); } DbgEx("buffer too long to show!show pre 50 hex! CWSCodec hex buf : %d : %s", num, str); return; } for (i = 0; i < num; i++) { sprintf(c, "%02X ", (unsigned char)buf[i]); strcat(str, c); } DbgEx("CWSCodec hex buf : %s", str); return; } std::string CWSCodec::GetEntityName(std::string strJson) { cJSON* pJson = cJSON_Parse(strJson.c_str()); char entity_name[64] = { 0 }; char errmsg[1024] = { 0 }; GetCJsonObjectValue(pJson, "entity", entity_name, errmsg); std::string s(entity_name); cJSON_Delete(pJson); return s; } std::string CWSCodec::GetClassName(std::string strJson) { cJSON* pJson = cJSON_Parse(strJson.c_str()); char class_name[64] = { 0 }; char errmsg[1024] = { 0 }; GetCJsonObjectValue(pJson, "class", class_name, errmsg); std::string s(class_name); cJSON_Delete(pJson); return s; } }