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