| | |
| | | |
| | | template <class T> T* ptrT(const size_t l=1){ return (T*)calloc(l, sizeof(T)); } |
| | | |
| | | static 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){ |
| | | static inline struct cstr null_cstr(){ |
| | | 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; |
| | | 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); |
| | |
| | | void cstr_free(struct cstr str){ |
| | | if (str.str && str.size) free(str.str); |
| | | } |
| | | struct cstrarr cstr_arr_new(const size_t len){ |
| | | static inline struct cstrarr null_cstr_arr(){ |
| | | struct cstrarr arr; |
| | | memset(&arr, 0, sizeof(arr)); |
| | | arr.arr = (struct cstr*)calloc(len, sizeof(struct cstr)); |
| | | arr.size = len; |
| | | 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->size && idx < arr->size){ |
| | | 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.size; i++){ |
| | | for(size_t i = 0; i < arr.count; i++){ |
| | | auto & str = arr.arr[i]; |
| | | cstr_free(str); |
| | | } |
| | | free(arr.arr); |
| | | } |
| | | |
| | | 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); |
| | | } |
| | | struct cproc* make_proc_info(const struct cstr name, const struct cstr id, const struct cstr info){ |
| | | auto proc = ptrT<struct cproc>(); |
| | | proc->name = cstr_clone(name); |
| | | proc->id = cstr_clone(id); |
| | | // proc->info = cstr_clone(info); |
| | | return proc; |
| | | } |
| | | |
| | | struct cproc* clone_proc_info(struct cproc* pi){ |
| | | struct cproc* clone_proc_info(const struct cproc* pi){ |
| | | if (!pi) return NULL; |
| | | auto newpi = ptrT<struct cproc>(); |
| | | *newpi = *pi; |
| | | newpi->name = cstr_clone(newpi->name); |
| | | newpi->id = cstr_clone(newpi->id); |
| | | // todo: ignore info |
| | |
| | | cstr_free(pi->id); |
| | | cstr_free(pi->info); |
| | | free(pi); |
| | | } |
| | | } |
| | | |
| | | 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); |
| | | } |
| | | } |
| | | |
| | |
| | | rinfo->pinfo = pinfo; |
| | | |
| | | auto assign_arr = [&obj](yyjson_val* v){ |
| | | const size_t size = yyjson_arr_size(v); |
| | | struct cstrarr arr; |
| | | memset(&arr, 0, sizeof(arr)); |
| | | arr.size = size; |
| | | for(size_t i = 0; i < size; i++){ |
| | | const size_t count = yyjson_arr_size(v); |
| | | struct cstrarr arr = cstr_arr_new(count); |
| | | for(size_t i = 0; i < count; i++){ |
| | | auto sv = yyjson_arr_get(v, i); |
| | | char* entry = NULL; |
| | | size_t entry_size = 0; |
| | |
| | | const size_t size = msg->msg.size; |
| | | |
| | | auto pl = ptrT<struct cproclist>(); |
| | | pl->cli = json2cclients(data, size, &pl->clientsize); |
| | | pl->cli = json2cclients(data, size, &pl->count); |
| | | return pl; |
| | | } |
| | | void free_submsg_proclist(struct cproclist* pl){ |
| | | if (pl) if (pl->cli) free_cclients(pl->cli, pl->clientsize); |
| | | if (pl) if (pl->cli) free_cclients(pl->cli, pl->count); |
| | | } |
| | | |
| | | ////////////////////////////////////////////////// |
| | | struct creq json2creq(const char* data, const size_t size){ |
| | | yyjson_doc* doc = yyjson_read(data, size, 0); |
| | | 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);}; |
| | | |
| | | struct creq req; |
| | | memset(&req, 0, sizeof(req)); |
| | | |
| | | auto jp = obj(root, "path"); |
| | | auto jb = obj(root, "body"); |
| | | req.path = cstr_new(yyjson_get_str(jp), yyjson_get_len(jp)); |
| | | req.body = cstr_new(yyjson_get_raw(jb), yyjson_get_len(jb)); |
| | | |
| | | 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 req; |
| | | return tp; |
| | | } |
| | | |
| | | struct creqmsg* to_reqmsg(const char* pid, const size_t pids, |
| | | const char* data, const size_t size, void* src) |
| | | 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); |
| | | MsgRequestTopic msgRT; |
| | | if (!msgRT.ParseFromArray(data, size)) return NULL; |
| | | msg->msg = cstr_new(msgRT.data().data(), msgRT.data().size()); |
| | | |
| | | // creg = msgRT.data(); |
| | | msg->msg = json2creq(data, size); |
| | | msg->src = src; |
| | | return msg; |
| | | } |
| | | |
| | | struct creqmsg* make_req_msg(const char* topic, const size_t topicl, |
| | | const char* data, const size_t datal) |
| | | { |
| | | auto msg = ptrT<struct creqmsg>(); |
| | | MsgRequestTopic msgRT; |
| | | msgRT.set_topic(topic, topicl); |
| | | msgRT.set_data(data, datal); |
| | | |
| | | auto pbstr = msgRT.SerializeAsString(); |
| | | msg->msg = cstr_new(pbstr.data(), pbstr.size()); |
| | | |
| | | return msg; |
| | | } |
| | | |
| | | void free_reqmsg(struct creqmsg* msg){ |
| | | if (msg){ |
| | | cstr_free(msg->procid); |
| | | cstr_free(msg->msg.path); |
| | | cstr_free(msg->msg.body); |
| | | cstr_free(msg->msg); |
| | | free(msg); |
| | | } |
| | | } |
| | | |
| | | struct cstackmsgerr* get_reqmsg_stackerr(struct creqmsg* msg){ |
| | | auto &body = msg->msg.body; |
| | | struct cstr path = null_cstr(); |
| | | struct cstr body = null_cstr(); |
| | | tie(path, body) = json2reqmsg(msg->msg); |
| | | if (body.size == 0) return NULL; |
| | | |
| | | auto doc = yyjson_read(body.str, body.size, 0); |
| | | auto root = yyjson_doc_get_root(doc); |
| | | |
| | |
| | | stkmsg->stackid = cstr_new(yyjson_get_str(jsid), yyjson_get_len(jsid)); |
| | | stkmsg->fileid = cstr_new(yyjson_get_str(jfid), yyjson_get_len(jfid)); |
| | | yyjson_doc_free(doc); |
| | | |
| | | cstr_free(path); |
| | | cstr_free(body); |
| | | |
| | | return stkmsg; |
| | | } |
| | | void free_reqmsg_stackerr(struct cstackmsgerr* msg){ |
| | |
| | | } |
| | | // decode success msg |
| | | struct cstackmsg* get_reqmsg_stack(struct creqmsg* msg){ |
| | | auto &body = msg->msg.body; |
| | | struct cstr path = null_cstr(); |
| | | struct cstr body = null_cstr(); |
| | | tie(path, body) = json2reqmsg(msg->msg); |
| | | if (body.size == 0) return NULL; |
| | | |
| | | auto doc = yyjson_read(body.str, body.size, 0); |
| | | auto root = yyjson_doc_get_root(doc); |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | struct crepmsg* make_reply_msg(const int success, const char* msg, const size_t msgl, |
| | | struct crepmsg* make_reply_msg(const int errcode, const char* errmsg, const size_t emsgl, |
| | | const char* data, const size_t datal) |
| | | { |
| | | auto rmsg = ptrT<struct crepmsg>(); |
| | | // rmsg->success = success; |
| | | // rmsg->msg = cstr_new(msg, msgl); |
| | | // rmsg->data = cstr_new(msg, msgl); |
| | | auto msg = ptrT<struct crepmsg>(); |
| | | msg->errcode = errcode; |
| | | msg->errmsg = cstr_new(errmsg, emsgl); |
| | | msg->data = cstr_new(data, datal); |
| | | return msg; |
| | | } |
| | | |
| | | 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); |
| | | auto root = yyjson_mut_obj(doc); |
| | | yyjson_mut_obj_add_bool(doc, root, "success", !!success); |
| | | yyjson_mut_obj_add_strn(doc, root, "msg", msg, msgl); |
| | | yyjson_mut_obj_add_strn(doc, root, "data", data, datal); |
| | | |
| | | return rmsg; |
| | | size_t jsonl = 0; |
| | | 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->msg); |
| | | cstr_free(msg->errmsg); |
| | | cstr_free(msg->data); |
| | | free(msg); |
| | | } |