#if (defined _WIN32 || defined _WIN64) #include "stdafx.h" #endif #include "BufferOperation.h" #include "modp_b64.h" #include "SpHelper.h" #include "SpUtility.h" #include "CWSCodec.h" #include "MessageType.h" #include "Chromium_msg_g.h" #include #include #include #include #include "../../ThirdParty/Include/CJson/cJSON.h" #include #include #define DEFAULT_CAPACITY 20480 namespace Chromium { static HANDLE m_mutex; 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) { DbgEx("CWSCodec Constuctor"); m_AckCallbackList = new std::map(); m_EventCallbackList = new std::map*>(); } CWSCodec::~CWSCodec() { if (mInterpreter) { delete this->mInterpreter; } ::CloseHandle(m_mutex); } CWSCodec* CWSCodec::getInstance() { DbgEx("CWSCodec static method getInstance"); m_mutex = ::CreateMutex(NULL, FALSE, NULL); // DWORD d = WaitForSingleObject(m_mutex, INFINITE); static CWSCodec obj; // ::ReleaseMutex(m_mutex); return &obj; } void CWSCodec::setEntityHandler(CSmartPointer p) { this->m_pFunc = p; } void CWSCodec::init(const char* xmlPath) { DbgEx("CWSCodec method -> init"); mInterpreter = new CStructureInterpreter(xmlPath); } 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])); for (auto paramInfo : ts.mParamList) { for (auto repeatName : c_repeatParamList) { if (paramInfo.mName == repeatName) DbgEx("requestAck参数名字重复, error, %s", paramInfo.mName.c_str()); } } //存在脏数据,不做另外处理 try { while (i != ts.mParamList.end()) { bool t_isRepeat = false; for (auto repeatName : c_repeatParamList) { 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") { u_int64_t 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 == "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_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_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()); } cJSON_AddStringToObject(ret, PARAMLIST_HEAD, cJSON_PrintUnformatted(extendJs.get())); //cJSON_AddItemToObject(ret, PARAMLIST_HEAD, extendJs.get()); } 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; for (auto it : ts.mParamList) errorMsg += it.mName + "--" + it.mType + "_"; DbgEx(errorMsg.c_str()); throw std::exception(std::logic_error("error DeserializeRequestAck")); } } 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; for (auto it : ts.mParamList) errorMsg += it.mName + "--" + it.mType + "_"; DbgEx(errorMsg.c_str()); throw std::exception(std::logic_error("error DeserializeRequestAck")); } } void receivehexdump(const char* buf, const int num) { char str[8192 * 2] = { 0 }; int i = 0; char c[5] = { 0 }; if (num > 1200) { 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! receivehexdump hex buf len = %d : %s", num, str); return; } for (i = 0; i < num; i++) { sprintf(c, "%02X ", (unsigned char)buf[i]); strcat(str, c); } DbgEx("receivehexdump hex buf len = %d : %s", num, str); return; } std::string CWSCodec::BufferToJson(CMessage& msg, int replaceTransId) { LOG_FUNCTION(); int rpos = 16; cJSON* ret = cJSON_CreateObject(); int errorCode = Error_Succeed; CSimpleStringA errorMsg = ""; receivehexdump(msg.getPayload(), msg.getLength()); if (msg.getLength() < 12) //End session len = 12 return std::string(); // 丢弃消息 // 通用反序列化 cJSON_AddNumberToObject(ret, "messageType", msg.getMessageType()); switch (msg.getMessageType()) { case RequestAck: cJSON_AddNumberToObject(ret, "sessionID", msg.getSessionID()); cJSON_AddNumberToObject(ret, "transID", replaceTransId != 0 ? replaceTransId : msg.getTransID()); cJSON_AddNumberToObject(ret, "isEnd", msg.getIsEnd()); rpos += 1; ReadT(msg.getPayload(), errorCode, &rpos); cJSON_AddNumberToObject(ret, "errorCode", errorCode); ReadT(msg.getPayload(), errorMsg, &rpos); cJSON_AddStringToObject(ret, "errorMsg", errorMsg); 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); cJSON_AddStringToObject(ret, "errorMsg", errorMsg); 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); cJSON_AddStringToObject(ret, "errorMsg", errorMsg); 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, sessionID=%d, transID=%d, replaceTransID=%d", msg.getMessageType(), msg.getSessionID(), msg.getTransID(), 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_AckCallbackList->erase(it); } // 有错误时直接返回 或者 不是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用户自定义部分反序列化 // 回调反序列化列表 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) { 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!"); 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 int transid = cJSON_GetObjectItem(pJson, "transId")->valueint; m_AckCallbackList->insert(std::pair(transid, st)); } } // 维护回调列表 Event if (Register == messageType) { std::vector* milist = NULL; entity_def_struct st = { 0 }; unsigned int transid = cJSON_GetObjectItem(pJson, "transId")->valueint; GetCJsonObjectValue(pJson, "entity", st.entity_name, errmsg); milist = mInterpreter->getAllMessageInterface(st.entity_name); m_EventCallbackList->insert(std::pair*>(transid, milist)); } 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("josn is too long, do not send out sp broadcast!"); return std::make_pair(messageType, nullptr); } if (Event == messageType) { 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); 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); // 写消息类型 WriteT(data, messageType, &wpos, &capacity); // 根据不同的request进行序列化 switch (messageType) { case Info: SerializeInfo(pJson, data, &wpos, &capacity, mi, errmsg); break; case BeginSession: SerializeBeginSession(pJson, data, &wpos, &capacity, mi, errmsg); break; case EndSession: SerializeEndSession(pJson, data, &wpos, &capacity, mi, errmsg); break; case Request: SerializeRequest(pJson, data, &wpos, &capacity, mi, errmsg); break; case Register: SerializeRegister(pJson, data, &wpos, &capacity, mi, errmsg); break; case Unregister: SerializeUnregister(pJson, data, &wpos, &capacity, mi, errmsg); break; case LogEventMsgType: SerializeLogEvent(pJson, data, &wpos, &capacity, mi, errmsg); break; case LogWarnMsgType: SerializeLogWarn(pJson, data, &wpos, &capacity, mi, errmsg); break; case SetVarReq: SerializeSetVarReq(pJson, data, &wpos, &capacity, mi, errmsg); break; case GetVarReq: SerializeGetVarReq(pJson, data, &wpos, &capacity, mi, errmsg); break; default: // warn break; }; // 修改头部的消息长度 int i = 0; len = wpos - 8; WriteT(data, len, &i, &capacity); 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::SerializeInfo(cJSON* js, char* data, int* wpos, int* capacity, CMedthodInterface* pI, char* errmsg) { int i4 = 0; i4 = cJSON_GetObjectItem(js, "sessionID")->valueint; WriteT(data, i4, wpos, capacity); i4 = cJSON_GetObjectItem(js, "methodID")->valueint; WriteT(data, i4, wpos, capacity); i4 = cJSON_GetObjectItem(js, "signature")->valueint; WriteT(data, i4, wpos, capacity); if (NULL == pI) { // 没有对应定义 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])); for (auto paramInfo : pI->mRequestInterpreter.mParamList) { for (auto repeatName : c_repeatParamList) { if (paramInfo.mName == repeatName) DbgEx("request参数名字重复, error, %s", paramInfo.mName.c_str()); } } //如果存在重复,可能数据已经脏了,所以也不需要作删除参数处理 paramJs = js; } GeneralSerialize(paramJs, data, wpos, capacity, pI, errmsg); return; } void CWSCodec::SerializeBeginSession(cJSON* js, char* data, int* wpos, int* capacity, CMedthodInterface* pI, char* errmsg) { unsigned int i4 = 0; GetCJsonIntergerValue(js, "transID", i4, errmsg); DbgEx("transId: %u", i4); 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) { int i4 = 0; i4 = cJSON_GetObjectItem(js, "sessionID")->valueint; WriteT(data, i4, wpos, capacity); } void CWSCodec::SerializeRequest(cJSON* js, char* data, int* wpos, int* capacity, CMedthodInterface* pI, char* errmsg) { unsigned int i4 = 0; GetCJsonIntergerValue(js, "transID", i4, errmsg); WriteT(data, i4, wpos, capacity); GetCJsonIntergerValue(js, "sessionID", i4, errmsg); WriteT(data, i4, wpos, capacity); GetCJsonIntergerValue(js, "methodID", i4, errmsg); WriteT(data, i4, wpos, capacity); GetCJsonIntergerValue(js, "signature", i4, errmsg); WriteT(data, i4, wpos, capacity); GetCJsonIntergerValue(js, "timeout", i4, errmsg); WriteT(data, i4, wpos, capacity); 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])); for (auto paramInfo : pI->mRequestInterpreter.mParamList) { for (auto repeatName : c_repeatParamList) { 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) { unsigned 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); s = ""; WriteT(data, s, wpos, capacity); } void CWSCodec::SerializeUnregister(cJSON* js, char* data, int* wpos, int* capacity, CMedthodInterface* pI, char* errmsg) { int i4 = 0; i4 = cJSON_GetObjectItem(js, "transID")->valueint; WriteT(data, i4, wpos, capacity); } void CWSCodec::SerializeLogEvent(cJSON* js, char* data, int* wpos, int* capacity, CMedthodInterface* pI, char* errmsg) { int i4 = 0; i4 = cJSON_GetObjectItem(js, "securityLevel")->valueint; WriteT(data, i4, wpos, capacity); i4 = cJSON_GetObjectItem(js, "eventCode")->valueint; WriteT(data, i4, wpos, capacity); CSimpleStringA s = ""; s = cJSON_GetObjectItem(js, "message")->valuestring; WriteT(data, s, wpos, capacity); } void CWSCodec::SerializeLogWarn(cJSON* js, char* data, int* wpos, int* capacity, CMedthodInterface* pI, char* errmsg) { int i4 = 0; i4 = cJSON_GetObjectItem(js, "securityLevel")->valueint; WriteT(data, i4, wpos, capacity); i4 = cJSON_GetObjectItem(js, "eventCode")->valueint; CSimpleStringA s = ""; s = cJSON_GetObjectItem(js, "message")->valuestring; WriteT(data, s, wpos, capacity); } void CWSCodec::SerializeSetVarReq(cJSON* js, char* data, int* wpos, int* capacity, CMedthodInterface* pI, char* errmsg) { int i4 = 0; i4 = cJSON_GetObjectItem(js, "transID")->valueint; WriteT(data, i4, wpos, capacity); CSimpleStringA s = ""; s = cJSON_GetObjectItem(js, "name")->valuestring; WriteT(data, s, wpos, capacity); s = cJSON_GetObjectItem(js, "value")->valuestring; WriteT(data, s, 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.push_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) { int i4 = 0; i4 = cJSON_GetObjectItem(js, "transID")->valueint; WriteT(data, i4, wpos, capacity); CSimpleStringA s = ""; s = cJSON_GetObjectItem(js, "name")->valuestring; WriteT(data, s, 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") { u_int64_t d = 0; 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_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)) 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)) 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)) 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)) break; WriteT(data, d, wpos, capacity); } } else { WriteT(data, len, wpos, capacity); } } else { DbgEx("GeneralSerialize error name -> type: %s -> %s", it->mName, it->mType); } ++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) { strncpy(dstValue, pTmpNode->valuestring, strlen(pTmpNode->valuestring)); ret = true; } else { 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) { CSimpleStringW wStr = ""; UTF8ToUnicode(pTmpNode->valuestring, wStr); dstValue = CSimpleStringW2A(wStr); ret = true; } else { 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) { UTF8ToUnicode(pTmpNode->valuestring, dstValue); ret = true; } else { 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{ 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{ 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{ 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{ 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 { 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 { 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{ 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 { 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)); CSimpleStringW strw = ""; UTF8ToUnicode(obj->valuestring, strw); dstValue = CSimpleStringW2A(strw); return true; } strcat(errmsg, "array member "); dstValue = ""; return false; } bool CWSCodec::GetCJsonObjectValue(cJSON* obj, CSimpleStringW& dstValue, char* errmsg) { if (cJSON_String == obj->type) { UTF8ToUnicode(obj->valuestring, dstValue); return true; } strcat(errmsg, "array member "); dstValue = ""; return false; } int CWSCodec::UTF8ToUnicode(char* input, CSimpleStringW& output) { #if (defined(_WIN32) || defined(_WIN64)) //UTF8 to Unicode //预转换,得到所需空间的大小 int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, input, strlen(input), NULL, 0); //分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间 WCHAR* wszString = new WCHAR[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 > 1200) { 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; } }