From e35a3ca104df1ae8d75c08900762990ef83fca6a Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Fri, 1 Oct 2021 09:13:46 +0800 Subject: [PATCH] sf_serializer.[hc]: support string array --- src/sf_serializer.c | 58 +++++++++++++++++++++++++++++++++++++++------ src/sf_serializer.h | 46 +++++++++++++++++++++++++++++++++-- 2 files changed, 95 insertions(+), 9 deletions(-) diff --git a/src/sf_serializer.c b/src/sf_serializer.c index a7ac266..ed0a1c0 100644 --- a/src/sf_serializer.c +++ b/src/sf_serializer.c @@ -49,6 +49,8 @@ static SFSerializerTypeConfig value_type_configs[SF_SERIALIZER_VALUE_TYPE_COUNT] {"int16_array", sizeof(SFSerializerPackFieldArray), 2}, {"int32_array", sizeof(SFSerializerPackFieldArray), 4}, {"int64_array", sizeof(SFSerializerPackFieldArray), 8}, + {"string_array", sizeof(SFSerializerPackFieldArray), + sizeof(SFSerializerPackStringValue)}, {"map", sizeof(SFSerializerPackFieldArray), 2 * sizeof(SFSerializerPackStringValue)} }; @@ -144,11 +146,11 @@ static inline int unpack_array_count(SFSerializerIterator *it, } min_size = value_type_configs[it->field.type].elt_size * (*count); - if (min_size > remain_len) { + if (remain_len < min_size) { snprintf(it->error_info, sizeof(it->error_info), - FIELD_ID_AND_TYPE_FORMAT", array min bytes: %d is " - "too large > remain: %d", FIELD_ID_AND_TYPE_PARAMS, - min_size, remain_len); + FIELD_ID_AND_TYPE_FORMAT", remain length: %d is too " + "small < array min bytes: %d", FIELD_ID_AND_TYPE_PARAMS, + remain_len, min_size); return EINVAL; } @@ -204,7 +206,7 @@ static inline int unpack_string(SFSerializerIterator *it, const int remain_len, sizeof(SFSerializerPackStringValue), output); } -static int unpack_array(SFSerializerIterator *it, const int remain_len) +static int unpack_integer_array(SFSerializerIterator *it, const int remain_len) { int result; int count; @@ -247,6 +249,40 @@ static int unpack_array(SFSerializerIterator *it, const int remain_len) return 0; } +static int unpack_string_array(SFSerializerIterator *it, const int remain_len) +{ + int result; + int count; + string_t *str; + string_t *end; + + if ((result=unpack_array_count(it, remain_len, &count)) != 0) { + return result; + } + + if (count > it->str_array_alloc) { + if ((result=array_expand(it, (void_array_t *)&it->str_array, + sizeof(string_t), count, &it->str_array_alloc)) != 0) + { + return result; + } + } + + it->p += sizeof(SFSerializerPackFieldArray); + end = it->str_array.strings + count; + for (str=it->str_array.strings; strend - it->p, + (SFSerializerPackStringValue *) + it->p, str)) != 0) + { + return result; + } + } + it->str_array.count = count; + + return 0; +} + static int unpack_map(SFSerializerIterator *it, const int remain_len) { int result; @@ -351,13 +387,21 @@ const SFSerializerFieldValue *sf_serializer_next(SFSerializerIterator *it) case sf_serializer_value_type_int16_array: case sf_serializer_value_type_int32_array: case sf_serializer_value_type_int64_array: - if ((it->error_no=unpack_array(it, remain_len - sizeof( - SFSerializerPackFieldArray))) != 0) + if ((it->error_no=unpack_integer_array(it, remain_len - + sizeof(SFSerializerPackFieldArray))) != 0) { return NULL; } it->field.value.int_array = it->int_array; break; + case sf_serializer_value_type_string_array: + if ((it->error_no=unpack_string_array(it, remain_len - sizeof( + SFSerializerPackFieldArray))) != 0) + { + return NULL; + } + it->field.value.str_array = it->str_array; + break; case sf_serializer_value_type_map: if ((it->error_no=unpack_map(it, remain_len - sizeof( SFSerializerPackFieldArray))) != 0) diff --git a/src/sf_serializer.h b/src/sf_serializer.h index fba0737..a0b2881 100644 --- a/src/sf_serializer.h +++ b/src/sf_serializer.h @@ -22,7 +22,7 @@ #include "fastcommon/fast_buffer.h" #include "fastcommon/hash.h" -#define SF_SERIALIZER_VALUE_TYPE_COUNT 10 +#define SF_SERIALIZER_VALUE_TYPE_COUNT 11 typedef enum { sf_serializer_value_type_int8 = 0, @@ -34,6 +34,7 @@ typedef enum { sf_serializer_value_type_int16_array, sf_serializer_value_type_int32_array, sf_serializer_value_type_int64_array, + sf_serializer_value_type_string_array, sf_serializer_value_type_map } SFSerializerValueType; @@ -93,6 +94,7 @@ typedef struct sf_serializer_field_value { string_t s; int64_array_t int_array; key_value_array_t kv_array; + string_array_t str_array; } value; } SFSerializerFieldValue; @@ -101,8 +103,10 @@ typedef struct sf_serializer_iterator { const char *end; int64_array_t int_array; //int64_t array holder key_value_array_t kv_array; //key-value array holder + string_array_t str_array; //string_t array holder int int_array_alloc; int kv_array_alloc; + int str_array_alloc; SFSerializerFieldValue field; int error_no; char error_info[256]; @@ -352,6 +356,39 @@ static inline int sf_serializer_pack_int64_array(FastBuffer *buffer, return 0; } +static inline int sf_serializer_pack_string_array(FastBuffer *buffer, + const unsigned char fid, const string_t *strings, const int count) +{ + int result; + int length; + SFSerializerPackFieldArray *obj; + const string_t *str; + const string_t *end; + SFSerializerPackStringValue *ps; + + length = sizeof(SFSerializerPackFieldArray); + end = strings + count; + for (str=strings; strlen; + } + + if ((result=fast_buffer_check_inc_size(buffer, length)) != 0) { + return result; + } + + obj = (SFSerializerPackFieldArray *)(buffer->data + buffer->length); + obj->field.id = fid; + obj->field.type = sf_serializer_value_type_string_array; + int2buff(count, obj->value.count); + + ps = (SFSerializerPackStringValue *)obj->value.ptr; + for (str=strings; strlength += length; + return 0; +} + static inline int sf_serializer_pack_map(FastBuffer *buffer, const unsigned char fid, const key_value_pair_t *kv_pairs, const int count) @@ -377,7 +414,7 @@ static inline int sf_serializer_pack_map(FastBuffer *buffer, obj = (SFSerializerPackFieldArray *)(buffer->data + buffer->length); obj->field.id = fid; obj->field.type = sf_serializer_value_type_map; - long2buff(count, obj->value.count); + int2buff(count, obj->value.count); ps = (SFSerializerPackStringValue *)obj->value.ptr; for (pair=kv_pairs; pairkv_array.kv_pairs); it->kv_array_alloc = 0; } + + if (it->str_array.strings != NULL) { + free(it->str_array.strings); + it->str_array_alloc = 0; + } } int sf_serializer_unpack(SFSerializerIterator *it, const string_t *content);