From f600bb176c1d2f0eeb5180637bdc09605b3d21bd Mon Sep 17 00:00:00 2001 From: zhangmeng <775834166@qq.com> Date: 星期三, 14 十二月 2022 14:58:28 +0800 Subject: [PATCH] restruct for easy use v1.1 --- message.cpp | 396 +++++++++++++++++++++++++++++++++----------------------- 1 files changed, 231 insertions(+), 165 deletions(-) diff --git a/message.cpp b/message.cpp index 9699470..614018c 100644 --- a/message.cpp +++ b/message.cpp @@ -20,91 +20,140 @@ using namespace std; +struct cstr{ + char* str; // 瀛楃涓插唴瀹� + size_t size; // 瀛楃涓查暱搴� +}; + +// 杩涚▼淇℃伅 +struct cproc{ + struct cstr name; // 杩涚▼鍚嶅瓧 + struct cstr id; // 杩涚▼id + struct cstr info; // 杩涚▼鍏朵粬淇℃伅锛岀洰鍓嶆病鐢� +}; + +struct creg{ + cproc* proc; // 闇�瑕佹敞鍐岀殑杩涚▼淇℃伅 + + char** channel; // 杩涚▼鎻愪緵鐨勮姹傚搷搴旀湇鍔$殑涓婚 + size_t channel_count; + char** pub; // 杩涚▼鎻愪緵鐨勫彂甯冭闃呯殑鍙戝竷涓婚 + size_t pub_count; + char** sub; // 杩涚▼闇�瑕佽闃呯殑涓婚 + size_t sub_count; + char** sub_net; // 杩涚▼闇�瑕佽闃呯殑缃戠粶涓婚锛岀洰鍓嶆病鐢� + size_t sub_net_count; +}; + template <class T> T* ptrT(const size_t l=1){ return (T*)calloc(l, sizeof(T)); } -static inline struct cstr null_cstr(){ +template<class T> struct rmC : remove_const<T>{}; +template<class T> struct rmC<const T*>{ using type = typename rmC<T>::type*; }; +template<class T> struct rmC<const T**>{ using type = typename rmC<T>::type**; }; +template <class T, typename enable_if<is_pointer<T>::value>::type* = nullptr> +typename rmC<T>::type rmConst(T t){ return const_cast<typename rmC<T>::type>(t); } + +static inline struct cstr cstr_ref(const char* str, const size_t len){ struct cstr cs; memset(&cs, 0, sizeof(cs)); - return cs; -} -static inline struct cstr cstr_ref(char* str, const size_t len){ - struct cstr cs = null_cstr(); cs.size = len; - cs.str = str; + cs.str = rmConst(str); return cs; -} -static inline struct cstr cstr_clone(const struct cstr old){ - return cstr_new(old.str, old.size); -} -struct cstr cstr_new(const char* str, const size_t len){ - struct cstr cs = null_cstr(); - cs.size = len; - cs.str = ptrT<char>(len); - memcpy(cs.str, str, len); - return cs; -} -void cstr_free(struct cstr str){ - if (str.str && str.size) free(str.str); -} -static inline struct cstrarr null_cstr_arr(){ - struct cstrarr arr; - memset(&arr, 0, sizeof(arr)); - return arr; -} -struct cstrarr cstr_arr_new(const size_t count){ - struct cstrarr arr = null_cstr_arr(); - arr.arr = (struct cstr*)calloc(count, sizeof(struct cstr)); - arr.count = count; - return arr; -} -void cstr_arr_add(struct cstrarr* arr, const char* data, const size_t len, const size_t idx){ - if (arr->arr && arr->count && idx < arr->count){ - arr->arr[idx] = cstr_new(data, len); - } -} -void cstr_arr_free(struct cstrarr arr){ - for(size_t i = 0; i < arr.count; i++){ - auto & str = arr.arr[i]; - cstr_free(str); - } - free(arr.arr); } -struct cproc* make_proc_info(const struct cstr name, const struct cstr id, const struct cstr info){ +static inline struct cstr cstr_clone(const struct cstr* str){ + struct cstr cs; + cs.size = str->size; + cs.str = ptrT<char>(cs.size); + memcpy(cs.str, str, cs.size); + return cs; +} + +cproc* internal_clone_cproc(const cproc* proc){ + auto nproc = ptrT<struct cproc>(); + nproc->name = cstr_clone(&proc->name); + nproc->id = cstr_clone(&proc->id); + return nproc; +} +void internal_cproc_free(cproc* proc){ + if (proc){ + free(proc->name.str); + free(proc->id.str); + free(proc->info.str); + free(proc); + } +} + +cproc* make_cproc(const char* name, const char* id){ auto proc = ptrT<struct cproc>(); - proc->name = cstr_clone(name); - proc->id = cstr_clone(id); - // proc->info = cstr_clone(info); + proc->name = cstr_ref(name, strlen(name)); + proc->id = cstr_ref(id, strlen(id)); return proc; } -struct cproc* clone_proc_info(const struct cproc* pi){ - if (!pi) return NULL; - auto newpi = ptrT<struct cproc>(); - newpi->name = cstr_clone(newpi->name); - newpi->id = cstr_clone(newpi->id); - // todo: ignore info - return newpi; +char* cproc_name(const cproc* proc){ + if (!proc) return NULL; + return proc->name.str; } -void free_proc_info(struct cproc* pi){ - if (pi){ - cstr_free(pi->name); - cstr_free(pi->id); - cstr_free(pi->info); - free(pi); - } +char* cproc_id(const cproc* proc){ + if (!proc) return NULL; + return proc->id.str; } -void free_creg(struct creg* reg){ - if (reg){ - if (reg->pinfo) free_proc_info(reg->pinfo); - cstr_arr_free(reg->channel); - cstr_arr_free(reg->topic_pub); - cstr_arr_free(reg->topic_sub); - cstr_arr_free(reg->topic_sub_net); - free(reg); - } +void cproc_free(cproc* proc){ + free(proc); +} + +creg* make_creg(const cproc* proc, const char** rep, const size_t repcnt, + const char** pub, const size_t pubcnt, + const char** sub, const size_t subcnt, + const char** subnet, const size_t subnetcnt) +{ + auto reg = ptrT<struct creg>(); + reg->proc = rmConst(proc); + reg->channel = rmConst(rep); + reg->channel_count = repcnt; + reg->pub = rmConst(pub); + reg->pub_count = pubcnt; + reg->sub = rmConst(sub); + reg->sub_count = subcnt; + reg->sub_net = rmConst(subnet); + reg->sub_net_count = subnetcnt; + return reg; +} + +const cproc* creg_proc(const creg* reg){ + if (!reg) return NULL; + return reg->proc; +} + +char** creg_rep_topic(const creg* reg, size_t* count){ + if (!reg) return NULL; + *count = reg->channel_count; + return reg->channel; +} + +char** creg_pub_topic(const creg* reg, size_t* count){ + if (!reg) return NULL; + *count = reg->pub_count; + return reg->pub; +} + +char** creg_sub_topic(const creg* reg, size_t* count){ + if (!reg) return NULL; + *count = reg->sub_count; + return reg->sub; +} + +char** creg_subnet_topic(const creg* reg, size_t* count){ + if (!reg) return NULL; + *count = reg->sub_net_count; + return reg->sub_net; +} + +void creg_free(creg* reg){ + free(reg); } ///////////////////////////////////////////////////////////////////// @@ -154,28 +203,21 @@ }; msg->table = (TableChanged)yyjson_get_int(obj("table")); msg->action = (DbAction)yyjson_get_int(obj("action")); - assign("id", &msg->id.str, &msg->id.size); - assign("info", &msg->info.str, &msg->info.size); + assign("id", &msg->id, &msg->idl); + assign("info", &msg->info, &msg->infol); yyjson_doc_free(doc); return msg; } static inline void freeDbChangeMsg(struct DbChangeMsg* msg){ if (msg){ - cstr_free(msg->id); - cstr_free(msg->info); + free(msg->id); + free(msg->info); free(msg); } } /////////////////////////////////////////////////////////////// - -static inline tuple<char*, size_t> parseTopic(MsgPublish &msgp, const char* data, const size_t size){ - if (!msgp.ParseFromArray(data, size)) return make_tuple(nullptr, 0); - auto tpc = ptrT<char>(msgp.topic().length()+1); - memcpy(tpc, msgp.topic().data(), msgp.topic().size()); - return make_tuple(tpc, msgp.topic().size()); -} static inline void json2str(yyjson_val* v, char** d, size_t* l){ *l = yyjson_get_len(v); @@ -183,7 +225,7 @@ memcpy(*d, yyjson_get_str(v), *l); } -static struct creg* jsonval2creg(yyjson_val* v){ +static struct creg* json2creg(yyjson_val* v){ auto obj = [](yyjson_val* v, const char* name){return yyjson_obj_get(v, name);}; auto rinfo = ptrT<struct creg>(); @@ -192,31 +234,47 @@ json2str(obj(pval, "name"), &pinfo->name.str, &pinfo->name.size); json2str(obj(pval, "id"), &pinfo->id.str, &pinfo->id.size); json2str(obj(pval, "info"), &pinfo->info.str, &pinfo->info.size); - rinfo->pinfo = pinfo; + rinfo->proc = pinfo; auto assign_arr = [&obj](yyjson_val* v){ const size_t count = yyjson_arr_size(v); - struct cstrarr arr = cstr_arr_new(count); + char** arr = ptrT<char*>(count); for(size_t i = 0; i < count; i++){ auto sv = yyjson_arr_get(v, i); char* entry = NULL; size_t entry_size = 0; json2str(sv, &entry, &entry_size); - arr.arr[i] = cstr_new(entry, entry_size); + arr[i] = ptrT<char>(entry_size+1); + memcpy(arr[i], entry, entry_size); } - return arr; + return make_tuple(arr, count); }; - rinfo->channel = assign_arr(obj(v, "channel")); - rinfo->topic_pub = assign_arr(obj(v, "pubTopic")); - rinfo->topic_sub = assign_arr(obj(v, "subTopic")); - rinfo->topic_sub_net = assign_arr(obj(v, "subNetTopic")); + tie(rinfo->channel, rinfo->channel_count) = assign_arr(obj(v, "channel")); + tie(rinfo->pub, rinfo->pub_count) = assign_arr(obj(v, "pubTopic")); + tie(rinfo->sub, rinfo->sub_count) = assign_arr(obj(v, "subTopic")); + tie(rinfo->sub_net, rinfo->sub_net_count) = assign_arr(obj(v, "subNetTopic")); return rinfo; } -static inline void free_cclients(struct cclient* cli, const size_t size){ - for(size_t i = 0; i < size; i++) if (cli[i].rinfo) free_creg(cli[i].rinfo); +static inline void free_cclients(struct cclient* cli, const size_t count){ + for(size_t i = 0; i < count; i++) { + if (cli[i].rinfo) { + auto tmp = cli[i].rinfo; + free(tmp->proc); + auto free_arr = [](char** arr, const size_t count){ + for(size_t i = 0; i < count; i++){ + free(arr[i]); + } + free(arr); + }; + free_arr(tmp->channel, tmp->channel_count); + free_arr(tmp->pub, tmp->pub_count); + free_arr(tmp->sub, tmp->sub_count); + free_arr(tmp->sub_net, tmp->sub_net_count); + }; + } free(cli); } @@ -235,7 +293,7 @@ rc.hbcnt = yyjson_get_int(obj(one, "heartbeatCount")); rc.dcnt = yyjson_get_int(obj(one, "deadCount")); rc.status = yyjson_get_int(obj(one, "status")); - rc.rinfo = jsonval2creg(obj(one, "info")); + rc.rinfo = json2creg(obj(one, "info")); cli[i] = rc; } @@ -320,8 +378,8 @@ *d = ptrT<char>(s.size()+1); memcpy(*d, s.data(), *l); }; - assign("id", &db->id.str, &db->id.size); - assign("info", &db->info.str, &db->info.size); + assign("id", &db->id, &db->idl); + assign("info", &db->info, &db->infol); // printf("table %d id %s act %d info %s\n", tbl, id.c_str(), act, info.c_str()); // string json; @@ -332,22 +390,31 @@ return db; } +static tuple<char*, size_t> copymemory(const char* src, const size_t size){ + char* dst = ptrT<char>(size + 1); + memcpy(dst, src, size); + return make_tuple(dst, size); +} +static tuple<char*, size_t> copymemory(const string& src){ + char* dst = ptrT<char>(src.size() + 1); + memcpy(dst, src.data(), src.size()); + return make_tuple(dst, src.size()); +} struct csubmsg* to_submsg(const char* data, const size_t size){ + MsgPublish msg; - auto tp = parseTopic(msg, data, size); + if (!msg.ParseFromArray(data, size)) return NULL; + auto smsg = ptrT<struct csubmsg>(); + tie(smsg->topic, smsg->topicl) = copymemory(msg.topic()); + tie(smsg->msg, smsg->msgl) = copymemory(msg.data()); - auto pmsg = ptrT<struct csubmsg>(); - pmsg->topic = cstr_new(get<0>(tp), get<1>(tp)); - - pmsg->msg = cstr_new(msg.data().data(), msg.data().size()); - - return pmsg; + return smsg; } void free_submsg(struct csubmsg* msg){ if (msg){ - cstr_free(msg->topic); - cstr_free(msg->msg); + free(msg->topic); + free(msg->msg); free(msg); } } @@ -355,15 +422,15 @@ struct DbChangeMsg* get_submsg_db(struct csubmsg* msg){ // string json = toJSON((const char*)msg->data, msg->size, "DbChangeMessage"); // return json2DbChangeMsg(json); - return pb2DbChangeMsg((const char*)msg->msg.str, msg->msg.size); + return pb2DbChangeMsg((const char*)msg->msg, msg->msgl); } void free_submsg_db(struct DbChangeMsg* msg){ if (msg) freeDbChangeMsg(msg); } struct cproclist* get_submsg_proclist(struct csubmsg* msg){ - const char* data = msg->msg.str; - const size_t size = msg->msg.size; + const char* data = msg->msg; + const size_t size = msg->msgl; auto pl = ptrT<struct cproclist>(); pl->cli = json2cclients(data, size, &pl->count); @@ -371,30 +438,19 @@ } void free_submsg_proclist(struct cproclist* pl){ if (pl) if (pl->cli) free_cclients(pl->cli, pl->count); + free(pl); } ////////////////////////////////////////////////// -static tuple<struct cstr, struct cstr> json2reqmsg(const struct cstr msg){ - yyjson_doc* doc = yyjson_read(msg.str, msg.size, 0); - yyjson_val* root = yyjson_doc_get_root(doc); - - auto obj = [](yyjson_val* v, const char* name){return yyjson_obj_get(v, name);}; - - auto jp = obj(root, "path"); - auto jb = obj(root, "body"); - auto tp = make_tuple(cstr_new(yyjson_get_str(jp), yyjson_get_len(jp)), - cstr_new(yyjson_get_raw(jb), yyjson_get_len(jb))); - yyjson_doc_free(doc); - return tp; -} struct creqmsg* to_reqmsg(const char* pid, const size_t pids, const char* data, const size_t size) { auto msg = ptrT<struct creqmsg>(); - msg->procid = cstr_new(pid, pids); + tie(msg->procid, msg->procidl) = copymemory(pid, pids); + MsgRequestTopic msgRT; if (!msgRT.ParseFromArray(data, size)) return NULL; - msg->msg = cstr_new(msgRT.data().data(), msgRT.data().size()); + tie(msg->msg, msg->msgl) = copymemory(msgRT.data()); return msg; } @@ -408,68 +464,77 @@ msgRT.set_data(data, datal); auto pbstr = msgRT.SerializeAsString(); - msg->msg = cstr_new(pbstr.data(), pbstr.size()); + tie(msg->msg, msg->msgl) = copymemory(pbstr); return msg; } void free_reqmsg(struct creqmsg* msg){ if (msg){ - cstr_free(msg->procid); - cstr_free(msg->msg); + free(msg->procid); + free(msg->msg); free(msg); } } -struct cstackmsgerr* get_reqmsg_stackerr(struct creqmsg* msg){ - struct cstr path = null_cstr(); - struct cstr body = null_cstr(); - tie(path, body) = json2reqmsg(msg->msg); - if (body.size == 0) return NULL; +static tuple<const char*, size_t> json2body(yyjson_doc* doc){ + yyjson_val* root = yyjson_doc_get_root(doc); - auto doc = yyjson_read(body.str, body.size, 0); + auto obj = [](yyjson_val* v, const char* name){return yyjson_obj_get(v, name);}; + + auto jp = obj(root, "path"); + if (!jp) return make_tuple((const char*)NULL, 0); + auto jb = obj(root, "body"); + if (!jb) return make_tuple((const char*)NULL, 0); + return make_tuple(yyjson_get_str(jb), yyjson_get_len(jp)); +} + +struct cstackmsgerr* get_reqmsg_stackerr(struct creqmsg* msg){ + auto doc0 = yyjson_read(msg->msg, msg->msgl, 0); + auto tpbody = json2body(doc0); + if (!get<0>(tpbody)) return NULL; + + auto doc = yyjson_read(get<0>(tpbody), get<1>(tpbody), 0); auto root = yyjson_doc_get_root(doc); auto obj = [](yyjson_val* v, const char* name){return yyjson_obj_get(v, name);}; auto jsid = obj(root, "stackId"); auto jfid = obj(root, "fileId"); - auto stkmsg = ptrT<struct cstackmsgerr>(); - stkmsg->stackid = cstr_new(yyjson_get_str(jsid), yyjson_get_len(jsid)); - stkmsg->fileid = cstr_new(yyjson_get_str(jfid), yyjson_get_len(jfid)); + auto smsg = ptrT<struct cstackmsgerr>(); + tie(smsg->stackid, smsg->stackidl) = copymemory(yyjson_get_str(jsid), yyjson_get_len(jsid)); + tie(smsg->fileid, smsg->fileidl) = copymemory(yyjson_get_str(jfid), yyjson_get_len(jfid)); yyjson_doc_free(doc); - cstr_free(path); - cstr_free(body); + yyjson_doc_free(doc0); - return stkmsg; + return smsg; } void free_reqmsg_stackerr(struct cstackmsgerr* msg){ if (msg){ - cstr_free(msg->stackid); - cstr_free(msg->fileid); + free(msg->stackid); + free(msg->fileid); free(msg); } } // decode success msg struct cstackmsg* get_reqmsg_stack(struct creqmsg* msg){ - struct cstr path = null_cstr(); - struct cstr body = null_cstr(); - tie(path, body) = json2reqmsg(msg->msg); - if (body.size == 0) return NULL; + auto doc0 = yyjson_read(msg->msg, msg->msgl, 0); + auto tpbody = json2body(doc0); + if (!get<0>(tpbody)) return NULL; - auto doc = yyjson_read(body.str, body.size, 0); + auto doc = yyjson_read(get<0>(tpbody), get<1>(tpbody), 0); auto root = yyjson_doc_get_root(doc); auto obj = [](yyjson_val* v, const char* name){return yyjson_obj_get(v, name);}; auto assign = [&obj](yyjson_val* v, const char* name){ auto tmp(obj(v, name)); - return cstr_new(yyjson_get_str(tmp), yyjson_get_len(tmp)); + return copymemory(yyjson_get_str(tmp), yyjson_get_len(tmp)); }; auto smsg = ptrT<struct cstackmsg>(); smsg->procnum = yyjson_get_int(obj(root, "procNum")); - smsg->stackid = assign(root, "stackId"); - smsg->stackname = assign(root, "stackName"); + tie(smsg->stackid, smsg->stackidl) = assign(root, "stackId"); + tie(smsg->stackname, smsg->stacknamel) = assign(root, "stackName"); smsg->type = yyjson_get_int(obj(root, "type")); smsg->width = yyjson_get_int(obj(root, "resolution_width")); smsg->width = yyjson_get_int(obj(root, "resolution_height")); @@ -482,25 +547,26 @@ struct cstackfile file; memset(&file, 0, sizeof(file)); yyjson_val* one = yyjson_arr_get(arr, i); - file.id = assign(one, "id"); - file.name = assign(one, "name"); - file.path = assign(one, "path"); + tie(file.id, file.idl) = assign(one, "id"); + tie(file.name, file.namel) = assign(one, "name"); + tie(file.path, file.pathl) = assign(one, "path"); file.type = yyjson_get_int(obj(one, "type")); smsg->files[i] = file; } yyjson_doc_free(doc); + yyjson_doc_free(doc0); return smsg; } void free_reqmsg_stack(struct cstackmsg* msg){ if (msg){ - cstr_free(msg->stackid); - cstr_free(msg->stackname); + free(msg->stackid); + free(msg->stackname); for(size_t i = 0; i < msg->filescnt; i++){ - cstr_free(msg->files[i].id); - cstr_free(msg->files[i].name); - cstr_free(msg->files[i].path); + free(msg->files[i].id); + free(msg->files[i].name); + free(msg->files[i].path); } free(msg); } @@ -511,12 +577,20 @@ { auto msg = ptrT<struct crepmsg>(); msg->errcode = errcode; - msg->errmsg = cstr_new(errmsg, emsgl); - msg->data = cstr_new(data, datal); + tie(msg->errmsg, msg->errmsgl) = copymemory(errmsg, emsgl); + tie(msg->data, msg->datal) = copymemory(data, datal); return msg; } -struct cstr make_reply_msg_json(const int success, const char* msg, const size_t msgl, +void free_reply_msg(struct crepmsg* msg){ + if (msg){ + free(msg->errmsg); + free(msg->data); + free(msg); + } +} + +static struct cstr make_reply_msg_json(const int success, const char* msg, const size_t msgl, const char* data, const size_t datal) { auto doc = yyjson_mut_doc_new(NULL); @@ -529,12 +603,4 @@ char* json = yyjson_mut_val_write(root, 0, &jsonl); yyjson_mut_doc_free(doc); return cstr_ref(json, jsonl); -} - -void free_reply_msg(struct crepmsg* msg){ - if (msg){ - cstr_free(msg->errmsg); - cstr_free(msg->data); - free(msg); - } } -- Gitblit v1.8.0