📄 cl_msg_types.c
字号:
intstruct_netstringlen(size_t namlen, size_t vallen, const void* value){ int ret; const struct ha_msg* childmsg; int len; HA_MSG_ASSERT(value); (void)vallen; childmsg = (const struct ha_msg*)value; len = get_netstringlen(childmsg); ret = intlen(namlen) + namlen + 2; /*for name*/ ret += 4; /*for type*/ ret += intlen(len) + len + 2; /*for child msg*/ return ret; }static intlist_stringlen(size_t namlen, size_t vallen, const void* value){ (void)value; return namlen + vallen + 2 + 3; /*overhead 3 is for type (FT_STRUCT)*/}static intlist_netstringlen(size_t namlen, size_t vallen, const void* value){ int ret; (void)value; ret = intlen(namlen) + (namlen) + intlen(vallen) + vallen + 4 ; ret += 4; /*for type*/ return ret;}static int add_binary_field(struct ha_msg* msg, char* name, size_t namelen, void* value, size_t vallen, int depth){ int next; if ( !msg || !name || !value || depth < 0){ cl_log(LOG_ERR, "add_binary_field:" " invalid input argument"); return HA_FAIL; } next = msg->nfields; msg->names[next] = name; msg->nlens[next] = namelen; msg->values[next] = value; msg->vlens[next] = vallen; msg->stringlen += binary_stringlen(namelen, vallen, value); msg->netstringlen += binary_netstringlen(namelen, vallen, value); msg->types[next] = FT_BINARY; msg->nfields++; return HA_OK;}static int add_struct_field(struct ha_msg* msg, char* name, size_t namelen, void* value, size_t vallen, int depth){ int next; struct ha_msg* childmsg; if ( !msg || !name || !value || depth < 0){ cl_log(LOG_ERR, "add_struct_field:" " invalid input argument"); return HA_FAIL; } childmsg = (struct ha_msg*)value; next = msg->nfields; msg->names[next] = name; msg->nlens[next] = namelen; msg->values[next] = value; msg->vlens[next] = vallen; msg->types[next] = FT_STRUCT; msg->nfields++; return HA_OK;}static int add_list_field(struct ha_msg* msg, char* name, size_t namelen, void* value, size_t vallen, int depth){ int next; int j; GList* list = NULL; int stringlen_add; int netstringlen_add; if ( !msg || !name || !value || namelen <= 0 || vallen <= 0 || depth < 0){ cl_log(LOG_ERR, "add_list_field:" " invalid input argument"); return HA_FAIL; } for (j=0; j < msg->nfields; ++j) { if (strcmp(name, msg->names[j]) == 0) { break; } } if ( j >= msg->nfields){ int listlen; list = (GList*)value; listlen = string_list_pack_length(list); stringlen_add = list_stringlen(namelen,listlen , value); netstringlen_add = list_netstringlen(namelen, listlen, value); next = msg->nfields; msg->names[next] = name; msg->nlens[next] = namelen; msg->values[next] = value; msg->vlens[next] = vallen; msg->types[next] = FT_LIST; msg->stringlen += stringlen_add; msg->netstringlen += netstringlen_add; msg->nfields++; } else if( msg->types[j] == FT_LIST ){ GList* oldlist = (GList*) msg->values[j]; int oldlistlen = string_list_pack_length(oldlist); int newlistlen; size_t i; for ( i =0; i < g_list_length((GList*)value); i++){ list = g_list_append(oldlist, g_list_nth_data((GList*)value, i)); } if (list == NULL){ cl_log(LOG_ERR, "add_list_field:" " g_list_append() failed"); return HA_FAIL; } newlistlen = string_list_pack_length(list); stringlen_add = newlistlen - oldlistlen; netstringlen_add = intlen(newlistlen) + newlistlen - intlen(oldlistlen) - oldlistlen; msg->values[j] = list; msg->vlens[j] = string_list_pack_length(list); msg->stringlen += stringlen_add; msg->netstringlen += netstringlen_add; g_list_free((GList*)value); /*we don't free each element because they are used in new list*/ } else { cl_log(LOG_ERR, "field already exists " "with differnt type=%d", msg->types[j]); return (HA_FAIL); } return HA_OK;}/*print a string to a string, pretty simple one :)*/static intstr2string(char* buf, char* maxp, void* value, size_t len, int depth){ char* s = value; (void)maxp; (void)depth; if ( strlen(s) != len){ cl_log(LOG_ERR, "str2string:" "the input len != string length"); return -1; } strcat(buf, s); return len; }/*print a binary value to a string using base64 library */static intbinary2string(char* buf, char* maxp, void* value, size_t len, int depth){ int baselen; int truelen = 0; (void)depth; baselen = B64_stringlen(len) + 1; if ( buf + baselen >= maxp){ cl_log(LOG_ERR, "binary2string: out of bounary"); return -1; } truelen = binary_to_base64(value, len, buf, baselen); return truelen;}/*print a struct(ha_msg) to a string @depth denotes the number of recursion*/static intstruct2string(char* buf, char* maxp, void* value, size_t len, int depth){ struct ha_msg* msg = value; int baselen = get_stringlen(msg); (void)len; if ( buf + baselen > maxp){ cl_log(LOG_ERR, "struct2string: not enough buffer" "for the struct to generate a string"); return -1; } if (msg2string_buf(msg, buf ,baselen,depth + 1, NEEDHEAD) != HA_OK){ cl_log(LOG_ERR , "struct2string(): msg2string_buf for" " child message failed"); return -1; } if (convert(buf, baselen, depth, NL_TO_SYM) != HA_OK){ cl_log(LOG_ERR , "struct2string(): convert failed"); return -1; } return strlen(buf);}/* print a list to a string */static intlist2string(char* buf, char* maxp, void* value, size_t len, int depth){ int listlen; GList* list = (GList*) value; (void)len; (void)depth; listlen = string_list_pack(list , buf, maxp); if (listlen == 0){ cl_log(LOG_ERR, "list2string():" "string_list_pack() failed"); return -1; } return listlen; }static intstring2str(void* value, size_t len, int depth, void** nv, size_t* nlen ){ if (!value || !nv || !nlen || depth < 0){ cl_log(LOG_ERR, "string2str:invalid input"); return HA_FAIL; } *nv = value; *nlen = len; return HA_OK;}static intstring2binary(void* value, size_t len, int depth, void** nv, size_t* nlen){ char tmpbuf[MAXMSG]; if (value == NULL && len == 0){ *nv = NULL; *nlen = 0; return HA_OK; } if ( !value || !nv || depth < 0){ cl_log(LOG_ERR, "string2binary:invalid input"); return HA_FAIL; } memcpy(tmpbuf, value, len); *nlen = base64_to_binary(tmpbuf, len, value, len); *nv = value; return HA_OK;}static intstring2struct(void* value, size_t vallen, int depth, void** nv, size_t* nlen){ struct ha_msg *tmpmsg; if (!value || !nv || depth < 0){ cl_log(LOG_ERR, "string2struct:invalid input"); return HA_FAIL; } if (convert(value, vallen, depth,SYM_TO_NL) != HA_OK){ cl_log(LOG_ERR , "ha_msg_addraw_ll(): convert failed"); return(HA_FAIL); } tmpmsg = string2msg_ll(value, vallen,depth + 1, 0); if (tmpmsg == NULL){ cl_log(LOG_ERR , "string2struct()" ": string2msg_ll failed"); return(HA_FAIL); } ha_free(value); *nv = tmpmsg; *nlen = 0; return HA_OK;}static intstring2list(void* value, size_t vallen, int depth, void** nv, size_t* nlen){ GList* list; if (!value || !nv || !nlen || depth < 0){ cl_log(LOG_ERR, "string2struct:invalid input"); return HA_FAIL; } list = string_list_unpack(value, vallen); if (list == NULL){ cl_log(LOG_ERR, "ha_msg_addraw_ll():" "unpack_string_list failed: %s", (char*)value); return(HA_FAIL); } ha_free(value); *nv = (void*)list; *nlen = string_list_pack_length(list); return HA_OK;}static int string2netstring(char* sp, char* smax, void* value, size_t vallen, size_t* comlen){ if ( !sp || !smax || !value || !comlen ){ cl_log(LOG_ERR, "string2netstring:" "invalid input arguments"); return HA_FAIL; } return compose_netstring(sp, smax, value, vallen, comlen); }static intbinary2netstring(char* sp, char* smax, void* value, size_t vallen, size_t* comlen){ return string2netstring(sp, smax, value, vallen, comlen); }static intstruct2netstring(char* sp, char* smax, void* value, size_t vallen, size_t* comlen){ size_t tmplen; char *sp_save = sp; struct ha_msg* msg; int llen; (void)vallen; if ( !sp || !smax || !value || !comlen ){ cl_log(LOG_ERR, "struct2netstring:" "invalid input arguments"); return HA_FAIL; } msg = (struct ha_msg*) value; llen = get_netstringlen(msg); sp += sprintf(sp, "%ld:", (long)llen); if (msg2netstring_buf(msg, sp, llen, &tmplen) != HA_OK){ cl_log(LOG_ERR, "struct2netstring()" ": msg2netstring_buf() failed"); return(HA_FAIL); } sp +=llen; *sp++ = ','; *comlen = sp - sp_save; return HA_OK;}static intlist2netstring(char* sp, char* smax, void* value, size_t vallen, size_t* comlen){ int tmplen; GList* list = NULL; char buf[MAXLENGTH]; (void)vallen; if ( !sp || !smax || !value || !comlen ){ cl_log(LOG_ERR, "list2netstring:" "invalid input arguments"); return HA_FAIL; } list= (GList*) value; tmplen = string_list_pack_length(list); if (tmplen >= MAXLENGTH){ cl_log(LOG_ERR, "string list length exceeds limit"); return(HA_FAIL); } if (string_list_pack(list, buf, buf + MAXLENGTH) != tmplen ){ cl_log(LOG_ERR, "packing string list return wrong length"); return(HA_FAIL); } if (compose_netstring(sp, smax, buf, tmplen, comlen) != HA_OK){ cl_log(LOG_ERR, "list2netstring: compose_netstring fails for" " value"); return(HA_FAIL); } return HA_OK; }static intnetstring2string(const void* value, size_t vlen, void** retvalue, size_t* ret_vlen){ char* dupvalue; if (value == NULL && vlen == 0){ *retvalue = NULL; *ret_vlen = 0; return HA_OK; } if ( !value || !retvalue || !ret_vlen){ cl_log(LOG_ERR, " netstring2string:" "invalid input arguments"); return HA_FAIL; } dupvalue = string_dup(value, vlen); if (!dupvalue){ cl_log(LOG_ERR, "netstring2string:" "duplicating value failed"); return HA_FAIL; } *retvalue = dupvalue; *ret_vlen = vlen; return HA_OK;}static intnetstring2binary(const void* value, size_t vlen, void** retvalue, size_t* ret_vlen){ return netstring2string(value, vlen, retvalue, ret_vlen); }static intnetstring2struct(const void* value, size_t vlen, void** retvalue, size_t* ret_vlen){ struct ha_msg* msg; if ( !value || !retvalue || !ret_vlen){ cl_log(LOG_ERR, " netstring2struct:" "invalid input arguments"); return HA_FAIL; } msg = netstring2msg(value, vlen, 1); if (!msg){ cl_log(LOG_ERR, "netstring2struct:" "netstring2msg failed"); return HA_FAIL; } *retvalue =(void* ) msg; *ret_vlen = 0; return HA_OK; }static intnetstring2list(const void* value, size_t vlen, void** retvalue, size_t* ret_vlen){ GList* list; if ( !value || !retvalue || !ret_vlen){ cl_log(LOG_ERR, " netstring2struct:" "invalid input arguments"); return HA_FAIL; } list = string_list_unpack(value, vlen); if (list == NULL){ cl_log(LOG_ERR, "netstring2list: unpacking string list failed"); cl_log(LOG_INFO, "thisbuf=%s", (const char*)value); return HA_FAIL; } *retvalue = (void*)list; *ret_vlen = string_list_pack_length(list); return HA_OK; }static int add_string_field(struct ha_msg* msg, char* name, size_t namelen, void* value, size_t vallen, int depth){ size_t internal_type; unsigned long tmptype; char *cp_name = NULL; size_t cp_namelen; size_t cp_vallen; void *cp_value = NULL; int next; int stringlen_add = 0 ; int netstringlen_add =0; if ( !msg || !name || !value || namelen <= 0 || depth < 0){ cl_log(LOG_ERR, "add_string_field:" " invalid input argument"); return HA_FAIL; } internal_type = FT_STRING; if (name[0] == '('){ int nlo = 3; /*name length overhead */ if (name[2] != ')'){ if (!cl_msg_quiet_fmterr) { cl_log(LOG_ERR , "ha_msg_addraw_ll(): no closing parentheses"); } return(HA_FAIL); } sscanf(name + 1, "%lu", &tmptype); internal_type = tmptype; if (internal_type == FT_STRING){ cl_log(LOG_ERR , "ha_msg_addraw_ll(): wrong type"); return(HA_FAIL); } cp_name = name; cp_namelen = namelen - nlo ; memmove(cp_name, name + nlo, namelen - nlo); cp_name[namelen - nlo] = EOS; }else { cp_name = name; cp_namelen = namelen; } if(internal_type < sizeof(fieldtypefuncs) / sizeof(fieldtypefuncs[0])){ int (*stringtofield)(void*, size_t, int depth, void**, size_t* ); int (*fieldstringlen)( size_t, size_t, const void*); int (*fieldnetstringlen)( size_t, size_t, const void*); stringtofield= fieldtypefuncs[internal_type].stringtofield; if (!stringtofield || stringtofield(value, vallen, depth, &cp_value, &cp_vallen) != HA_OK){ cl_log(LOG_ERR, "add_string_field: stringtofield failed"); return HA_FAIL; } fieldstringlen = fieldtypefuncs[internal_type].stringlen; if (!fieldstringlen || (stringlen_add = fieldstringlen(cp_namelen, cp_vallen, cp_value)) <= 0 ){ cl_log(LOG_ERR, "add_string_field: stringlen failed"); return HA_FAIL; } fieldnetstringlen = fieldtypefuncs[internal_type].netstringlen; if (!fieldnetstringlen || (netstringlen_add = fieldnetstringlen(cp_namelen, cp_vallen, cp_value)) <= 0 ){ cl_log(LOG_ERR, "add_string_field: netstringlen failed"); return HA_FAIL; } } else { cl_log(LOG_ERR, "add_string_field():" " wrong type %lu", (unsigned long)internal_type); return HA_FAIL; } next = msg->nfields; msg->values[next] = cp_value; msg->vlens[next] = cp_vallen; msg->names[next] = cp_name; msg->nlens[next] = cp_namelen; if (internal_type != FT_STRUCT){ msg->stringlen += stringlen_add; msg->netstringlen += netstringlen_add; } msg->types[next] = internal_type; msg->nfields++; return HA_OK; }struct fieldtypefuncs_s fieldtypefuncs[4]= { {string_memfree, string_dup, string_display, add_string_field, string_stringlen,string_netstringlen, str2string,string2netstring, string2str, netstring2string}, {binary_memfree, binary_dup, binary_display, add_binary_field, binary_stringlen,binary_netstringlen, binary2string,binary2netstring, string2binary, netstring2binary}, {struct_memfree, struct_dup, struct_display, add_struct_field, struct_stringlen, struct_netstringlen, struct2string, struct2netstring, string2struct, netstring2struct}, {list_memfree, list_dup, list_display, add_list_field, list_stringlen, list_netstringlen, list2string, list2netstring, string2list, netstring2list}, };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -