From cc5f215a3a61e139c02957b7c2b479a793dd0498 Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Fri, 20 Aug 2021 17:36:06 +0800 Subject: [PATCH] sf_serialize_next return array and map correctly --- src/sf_serialize.c | 56 +++++++++++++++++++++++++++++----------------- src/sf_serialize.h | 10 ++++----- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/sf_serialize.c b/src/sf_serialize.c index cabc917..7de0984 100644 --- a/src/sf_serialize.c +++ b/src/sf_serialize.c @@ -27,21 +27,27 @@ #include "fastcommon/logger.h" #include "sf_serialize.h" +#define FIELD_ID_AND_TYPE_FORMAT "fid: %d, type: %s" +#define FIELD_ID_AND_TYPE_PARAMS it->field.fid, \ + value_type_configs[it->field.type].name + + typedef struct { + const char *name; int min_size; int elt_size; } SFSerializeTypeConfig; static SFSerializeTypeConfig value_type_configs[SF_SERIALIZE_VALUE_TYPE_COUNT] = { - {sizeof(SFSerializePackFieldInt8), 0}, - {sizeof(SFSerializePackFieldInt16), 0}, - {sizeof(SFSerializePackFieldInt32), 0}, - {sizeof(SFSerializePackFieldInt64), 0}, - {sizeof(SFSerializePackStringValue), 0}, - {sizeof(SFSerializePackFieldArray), 4}, - {sizeof(SFSerializePackFieldArray), 8}, - {sizeof(SFSerializePackFieldArray), 2 * + {"int8", sizeof(SFSerializePackFieldInt8), 0}, + {"int16", sizeof(SFSerializePackFieldInt16), 0}, + {"int32", sizeof(SFSerializePackFieldInt32), 0}, + {"int64", sizeof(SFSerializePackFieldInt64), 0}, + {"string", sizeof(SFSerializePackStringValue), 0}, + {"int32_array", sizeof(SFSerializePackFieldArray), 4}, + {"int64_array", sizeof(SFSerializePackFieldArray), 8}, + {"map", sizeof(SFSerializePackFieldArray), 2 * sizeof(SFSerializePackStringValue)} }; @@ -87,13 +93,14 @@ static int check_field_type(SFSerializeIterator *it, { if (!(type >= 0 && type < SF_SERIALIZE_VALUE_TYPE_COUNT)) { snprintf(it->error_info, sizeof(it->error_info), - "unknown type: %d", type); + "fid: %d, unknown type: %d", it->field.fid, type); return EINVAL; } if (remain_len < value_type_configs[type].min_size) { snprintf(it->error_info, sizeof(it->error_info), - "remain length: %d is too small which < %d", + FIELD_ID_AND_TYPE_FORMAT", remain length: %d " + "is too small which < %d", FIELD_ID_AND_TYPE_PARAMS, remain_len, value_type_configs[type].min_size); return EINVAL; } @@ -105,13 +112,15 @@ static inline int check_string_value(SFSerializeIterator *it, { if (s->len < 0) { snprintf(it->error_info, sizeof(it->error_info), - "invalid string length: %d < 0", s->len); + FIELD_ID_AND_TYPE_FORMAT", invalid string length: %d < 0", + FIELD_ID_AND_TYPE_PARAMS, s->len); return EINVAL; } if (s->len > remain_len) { snprintf(it->error_info, sizeof(it->error_info), - "string length: %d is too large > remain length: %d", + FIELD_ID_AND_TYPE_FORMAT", string length: %d is too " + "large > remain length: %d", FIELD_ID_AND_TYPE_PARAMS, s->len, remain_len); return EINVAL; } @@ -127,14 +136,16 @@ static inline int unpack_array_count(SFSerializeIterator *it, *count = buff2int(((SFSerializePackFieldArray *)it->p)->value.count); if (*count < 0) { snprintf(it->error_info, sizeof(it->error_info), - "invalid array count: %d < 0", *count); + FIELD_ID_AND_TYPE_FORMAT", invalid array count: %d < 0", + FIELD_ID_AND_TYPE_PARAMS, *count); return EINVAL; } min_size = value_type_configs[it->field.type].elt_size * (*count); if (min_size > remain_len) { snprintf(it->error_info, sizeof(it->error_info), - "array min bytes: %d is too large > remain: %d", + FIELD_ID_AND_TYPE_FORMAT", array min bytes: %d is " + "too large > remain: %d", FIELD_ID_AND_TYPE_PARAMS, min_size, remain_len); return EINVAL; } @@ -142,8 +153,8 @@ static inline int unpack_array_count(SFSerializeIterator *it, return 0; } -static int array_expand(void_array_t *array, const int elt_size, - const int target_count, int *alloc_size) +static int array_expand(SFSerializeIterator *it, void_array_t *array, + const int elt_size, const int target_count, int *alloc_size) { int new_alloc; void *new_elts; @@ -159,6 +170,9 @@ static int array_expand(void_array_t *array, const int elt_size, new_elts = fc_malloc(elt_size * new_alloc); if (new_elts == NULL) { + snprintf(it->error_info, sizeof(it->error_info), + FIELD_ID_AND_TYPE_FORMAT", malloc %d bytes fail", + FIELD_ID_AND_TYPE_PARAMS, elt_size * new_alloc); return ENOMEM; } @@ -175,7 +189,8 @@ static inline int unpack_string(SFSerializeIterator *it, const int remain_len, { if (remain_len < sizeof(SFSerializePackStringValue)) { snprintf(it->error_info, sizeof(it->error_info), - "remain length: %d is too small < %d", + FIELD_ID_AND_TYPE_FORMAT", remain length: %d " + "is too small < %d", FIELD_ID_AND_TYPE_PARAMS, remain_len, (int)sizeof(SFSerializePackStringValue)); return EINVAL; } @@ -199,7 +214,7 @@ static int unpack_array(SFSerializeIterator *it, const int remain_len) } if (count > it->int_array_alloc) { - if ((result=array_expand((void_array_t *)&it->int_array, + if ((result=array_expand(it, (void_array_t *)&it->int_array, sizeof(int64_t), count, &it->int_array_alloc)) != 0) { return result; @@ -233,7 +248,7 @@ static int unpack_map(SFSerializeIterator *it, const int remain_len) } if (count > it->kv_array_alloc) { - if ((result=array_expand((void_array_t *)&it->kv_array, + if ((result=array_expand(it, (void_array_t *)&it->kv_array, sizeof(key_value_pair_t), count, &it->kv_array_alloc)) != 0) { @@ -282,7 +297,6 @@ const SFSerializeFieldValue *sf_serialize_next(SFSerializeIterator *it) } field = (SFSerializePackFieldInfo *)it->p; - it->field.fid = field->id; it->field.type = field->type; if ((it->error_no=check_field_type(it, remain_len, field->type)) != 0) { @@ -329,6 +343,7 @@ const SFSerializeFieldValue *sf_serialize_next(SFSerializeIterator *it) { return NULL; } + it->field.value.int_array = it->int_array; break; case sf_serialize_value_type_map: if ((it->error_no=unpack_map(it, remain_len - sizeof( @@ -336,6 +351,7 @@ const SFSerializeFieldValue *sf_serialize_next(SFSerializeIterator *it) { return NULL; } + it->field.value.kv_array = it->kv_array; break; } diff --git a/src/sf_serialize.h b/src/sf_serialize.h index 5bf957b..3748850 100644 --- a/src/sf_serialize.h +++ b/src/sf_serialize.h @@ -22,7 +22,7 @@ #include "fastcommon/fast_buffer.h" #include "fastcommon/hash.h" -#define SF_SERIALIZE_VALUE_TYPE_COUNT 8 +#define SF_SERIALIZE_VALUE_TYPE_COUNT 8 typedef enum { sf_serialize_value_type_int8 = 0, @@ -83,8 +83,6 @@ typedef struct sf_serialize_pack_field_array { } value; } SFSerializePackFieldArray; -#define SF_SERIALIZE_PACK_HEADER_SIZE sizeof(SFSerializePackHeader) - typedef struct sf_serialize_field_value { unsigned char fid; SFSerializeValueType type; @@ -99,8 +97,8 @@ typedef struct sf_serialize_field_value { typedef struct sf_serialize_iterator { const char *p; const char *end; - int64_array_t int_array; - key_value_array_t kv_array; + int64_array_t int_array; //int64_t array holder + key_value_array_t kv_array; //key-value array holder int int_array_alloc; int kv_array_alloc; SFSerializeFieldValue field; @@ -114,7 +112,7 @@ extern "C" { static inline void sf_serialize_pack_begin(FastBuffer *buffer) { - buffer->length = SF_SERIALIZE_PACK_HEADER_SIZE; + buffer->length = sizeof(SFSerializePackHeader); } static inline int sf_serialize_pack_int8(FastBuffer *buffer,