From 320f344b3e38419a504898ebd7da9905f508c192 Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Tue, 16 Nov 2021 10:08:40 +0800 Subject: [PATCH] sf_serializer.[hc]: support id_name_array --- src/sf_binlog_index.h | 4 +-- src/sf_serializer.c | 58 +++++++++++++++++++++++++++++++++ src/sf_serializer.h | 74 +++++++++++++++++++++++++++++++++---------- 3 files changed, 117 insertions(+), 19 deletions(-) diff --git a/src/sf_binlog_index.h b/src/sf_binlog_index.h index 1727fe4..f15f8fa 100644 --- a/src/sf_binlog_index.h +++ b/src/sf_binlog_index.h @@ -22,7 +22,7 @@ #define SF_BINLOG_PARSE_INT_SILENCE(var, caption, index, endchr, min_val) \ do { \ - var = strtol(cols[index].str, &endptr, 10); \ + var = strtoll(cols[index].str, &endptr, 10); \ if (*endptr != endchr || var < min_val) { \ sprintf(error_info, "invalid %s: %.*s", \ caption, cols[index].len, cols[index].str); \ @@ -32,7 +32,7 @@ #define SF_BINLOG_PARSE_INT_SILENCE2(var, caption, index, echr1, echr2, min_val) \ do { \ - var = strtol(cols[index].str, &endptr, 10); \ + var = strtoll(cols[index].str, &endptr, 10); \ if (!(*endptr == echr1 || *endptr == echr2) || (var < min_val)) { \ sprintf(error_info, "invalid %s: %.*s", \ caption, cols[index].len, cols[index].str); \ diff --git a/src/sf_serializer.c b/src/sf_serializer.c index ed0a1c0..2ddba3f 100644 --- a/src/sf_serializer.c +++ b/src/sf_serializer.c @@ -51,6 +51,8 @@ static SFSerializerTypeConfig value_type_configs[SF_SERIALIZER_VALUE_TYPE_COUNT] {"int64_array", sizeof(SFSerializerPackFieldArray), 8}, {"string_array", sizeof(SFSerializerPackFieldArray), sizeof(SFSerializerPackStringValue)}, + {"id_name_array", sizeof(SFSerializerPackFieldArray), + sizeof(int64_t) + sizeof(SFSerializerPackStringValue)}, {"map", sizeof(SFSerializerPackFieldArray), 2 * sizeof(SFSerializerPackStringValue)} }; @@ -283,6 +285,54 @@ static int unpack_string_array(SFSerializerIterator *it, const int remain_len) return 0; } +static int unpack_id_name_array(SFSerializerIterator *it, const int remain_len) +{ + int result; + int count; + id_name_pair_t *pair; + id_name_pair_t *end; + + if ((result=unpack_array_count(it, remain_len, &count)) != 0) { + return result; + } + + if (count > it->id_name_array_alloc) { + if ((result=array_expand(it, (void_array_t *)&it->id_name_array, + sizeof(id_name_pair_t), count, + &it->id_name_array_alloc)) != 0) + { + return result; + } + } + + it->p += sizeof(SFSerializerPackFieldArray); + end = it->id_name_array.elts + count; + for (pair=it->id_name_array.elts; pairend - it->p) < (sizeof(int64_t) + + sizeof(SFSerializerPackStringValue))) + { + snprintf(it->error_info, sizeof(it->error_info), + FIELD_ID_AND_TYPE_FORMAT", remain length: %d " + "is too small < %d", FIELD_ID_AND_TYPE_PARAMS, + (int)(it->end - it->p), (int)(sizeof(int64_t) + + sizeof(SFSerializerPackStringValue))); + return EINVAL; + } + + pair->id = buff2long(it->p); + it->p += sizeof(int64_t); + if ((result=unpack_string(it, it->end - it->p, + (SFSerializerPackStringValue *)it->p, + &pair->name)) != 0) + { + return result; + } + } + it->id_name_array.count = count; + + return 0; +} + static int unpack_map(SFSerializerIterator *it, const int remain_len) { int result; @@ -402,6 +452,14 @@ const SFSerializerFieldValue *sf_serializer_next(SFSerializerIterator *it) } it->field.value.str_array = it->str_array; break; + case sf_serializer_value_type_id_name_array: + if ((it->error_no=unpack_id_name_array(it, remain_len - + sizeof(SFSerializerPackFieldArray))) != 0) + { + return NULL; + } + it->field.value.id_name_array = it->id_name_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 aeff9eb..915fbda 100644 --- a/src/sf_serializer.h +++ b/src/sf_serializer.h @@ -23,7 +23,7 @@ #include "fastcommon/fast_buffer.h" #include "fastcommon/hash.h" -#define SF_SERIALIZER_VALUE_TYPE_COUNT 11 +#define SF_SERIALIZER_VALUE_TYPE_COUNT 12 typedef enum { sf_serializer_value_type_int8 = 0, @@ -36,6 +36,7 @@ typedef enum { sf_serializer_value_type_int32_array, sf_serializer_value_type_int64_array, sf_serializer_value_type_string_array, + sf_serializer_value_type_id_name_array, sf_serializer_value_type_map } SFSerializerValueType; @@ -94,20 +95,23 @@ typedef struct sf_serializer_field_value { int64_t n; string_t s; int64_array_t int_array; - key_value_array_t kv_array; string_array_t str_array; + id_name_array_t id_name_array; + key_value_array_t kv_array; } value; } SFSerializerFieldValue; typedef struct sf_serializer_iterator { const char *p; 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 + int64_array_t int_array; //int64_t array holder + string_array_t str_array; //string_t array holder + id_name_array_t id_name_array; //id name array holder + key_value_array_t kv_array; //key value array holder int int_array_alloc; - int kv_array_alloc; int str_array_alloc; + int id_name_array_alloc; + int kv_array_alloc; SFSerializerFieldValue field; int error_no; char error_info[256]; @@ -224,10 +228,9 @@ static inline int sf_serializer_pack_integer(FastBuffer *buffer, int2buff((value)->len, (ps)->len); \ memcpy((ps)->str, (value)->str, (value)->len) -#define SF_SERIALIZER_PACK_STRING_AND_MOVE_PTR(ps, value) \ - SF_SERIALIZER_PACK_STRING(ps, value); \ - ps = (SFSerializerPackStringValue *)(((char *)ps) + sizeof( \ - SFSerializerPackStringValue) + (value)->len) +#define SF_SERIALIZER_PACK_STRING_AND_MOVE_PTR(p, value) \ + SF_SERIALIZER_PACK_STRING((SFSerializerPackStringValue *)p, value); \ + p += (sizeof(SFSerializerPackStringValue) + (value)->len) static inline int sf_serializer_pack_string(FastBuffer *buffer, const unsigned char fid, const string_t *value) @@ -373,7 +376,7 @@ static inline int sf_serializer_pack_string_array(FastBuffer *buffer, SFSerializerPackFieldArray *obj; const string_t *str; const string_t *end; - SFSerializerPackStringValue *ps; + char *p; length = sizeof(SFSerializerPackFieldArray); end = strings + count; @@ -390,9 +393,46 @@ static inline int sf_serializer_pack_string_array(FastBuffer *buffer, obj->field.type = sf_serializer_value_type_string_array; int2buff(count, obj->value.count); - ps = (SFSerializerPackStringValue *)obj->value.ptr; + p = obj->value.ptr; for (str=strings; strlength += length; + return 0; +} + +static inline int sf_serializer_pack_id_name_array(FastBuffer *buffer, + const unsigned char fid, const id_name_pair_t *in_pairs, + const int count) +{ + int result; + int length; + SFSerializerPackFieldArray *obj; + const id_name_pair_t *pair; + const id_name_pair_t *end; + char *p; + + length = sizeof(SFSerializerPackFieldArray); + end = in_pairs + count; + for (pair=in_pairs; pairname.len + + sizeof(SFSerializerPackStringValue); + } + + 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_id_name_array; + int2buff(count, obj->value.count); + + p = obj->value.ptr; + for (pair=in_pairs; pairid, p); + p += sizeof(int64_t); + SF_SERIALIZER_PACK_STRING_AND_MOVE_PTR(p, &pair->name); } buffer->length += length; return 0; @@ -407,7 +447,7 @@ static inline int sf_serializer_pack_map(FastBuffer *buffer, SFSerializerPackFieldArray *obj; const key_value_pair_t *pair; const key_value_pair_t *end; - SFSerializerPackStringValue *ps; + char *p; length = sizeof(SFSerializerPackFieldArray); end = kv_pairs + count; @@ -425,10 +465,10 @@ static inline int sf_serializer_pack_map(FastBuffer *buffer, obj->field.type = sf_serializer_value_type_map; int2buff(count, obj->value.count); - ps = (SFSerializerPackStringValue *)obj->value.ptr; + p = obj->value.ptr; for (pair=kv_pairs; pairkey); - SF_SERIALIZER_PACK_STRING_AND_MOVE_PTR(ps, &pair->value); + SF_SERIALIZER_PACK_STRING_AND_MOVE_PTR(p, &pair->key); + SF_SERIALIZER_PACK_STRING_AND_MOVE_PTR(p, &pair->value); } buffer->length += length; return 0;