diff --git a/src/Makefile.in b/src/Makefile.in index 209dae1..a9a29be 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -8,7 +8,7 @@ TARGET_LIB = $(TARGET_PREFIX)/$(LIB_VERSION) TOP_HEADERS = sf_types.h sf_global.h sf_define.h sf_nio.h sf_service.h \ sf_func.h sf_util.h sf_configs.h sf_proto.h sf_binlog_writer.h \ sf_cluster_cfg.h sf_sharding_htable.h sf_connection_manager.h \ - sf_serialize.h sf_binlog_index.h + sf_serializer.h sf_binlog_index.h IDEMP_SERVER_HEADER = idempotency/server/server_types.h \ idempotency/server/server_channel.h \ @@ -27,7 +27,7 @@ SHARED_OBJS = sf_nio.lo sf_service.lo sf_global.lo \ sf_func.lo sf_util.lo sf_configs.lo sf_proto.lo \ sf_binlog_writer.lo sf_sharding_htable.lo \ sf_cluster_cfg.lo sf_connection_manager.lo \ - sf_serialize.lo sf_binlog_index.lo \ + sf_serializer.lo sf_binlog_index.lo \ idempotency/server/server_channel.lo \ idempotency/server/request_htable.lo \ idempotency/server/channel_htable.lo \ diff --git a/src/sf_serialize.h b/src/sf_serialize.h deleted file mode 100644 index 3748850..0000000 --- a/src/sf_serialize.h +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (c) 2020 YuQing <384681@qq.com> - * - * This program is free software: you can use, redistribute, and/or modify - * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -//sf_serialize.h - -#ifndef _SF_SERIALIZE_H -#define _SF_SERIALIZE_H - -#include "fastcommon/common_define.h" -#include "fastcommon/fast_buffer.h" -#include "fastcommon/hash.h" - -#define SF_SERIALIZE_VALUE_TYPE_COUNT 8 - -typedef enum { - sf_serialize_value_type_int8 = 0, - sf_serialize_value_type_int16, - sf_serialize_value_type_int32, - sf_serialize_value_type_int64, - sf_serialize_value_type_string, - sf_serialize_value_type_int32_array, - sf_serialize_value_type_int64_array, - sf_serialize_value_type_map -} SFSerializeValueType; - -typedef struct sf_serialize_pack_header { - char length[4]; - char crc32[4]; -} SFSerializePackHeader; - -typedef struct sf_serialize_pack_field_info { - unsigned char id; - unsigned char type; -} SFSerializePackFieldInfo; - -typedef struct sf_serialize_pack_field_int8 { - SFSerializePackFieldInfo field; - char value; -} SFSerializePackFieldInt8; - -typedef struct sf_serialize_pack_field_int16 { - SFSerializePackFieldInfo field; - char value[2]; -} SFSerializePackFieldInt16; - -typedef struct sf_serialize_pack_field_int32 { - SFSerializePackFieldInfo field; - char value[4]; -} SFSerializePackFieldInt32; - -typedef struct sf_serialize_pack_field_int64 { - SFSerializePackFieldInfo field; - char value[8]; -} SFSerializePackFieldInt64; - -typedef struct sf_serialize_pack_string_value { - char len[4]; - char str[0]; -} SFSerializePackStringValue; - -typedef struct sf_serialize_pack_field_string { - SFSerializePackFieldInfo field; - SFSerializePackStringValue value; -} SFSerializePackFieldString; - -typedef struct sf_serialize_pack_field_array { - SFSerializePackFieldInfo field; - struct { - char count[4]; - char ptr[0]; - } value; -} SFSerializePackFieldArray; - -typedef struct sf_serialize_field_value { - unsigned char fid; - SFSerializeValueType type; - union { - int64_t n; - string_t s; - int64_array_t int_array; - key_value_array_t kv_array; - } value; -} SFSerializeFieldValue; - -typedef struct sf_serialize_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 - int int_array_alloc; - int kv_array_alloc; - SFSerializeFieldValue field; - int error_no; - char error_info[256]; -} SFSerializeIterator; - -#ifdef __cplusplus -extern "C" { -#endif - -static inline void sf_serialize_pack_begin(FastBuffer *buffer) -{ - buffer->length = sizeof(SFSerializePackHeader); -} - -static inline int sf_serialize_pack_int8(FastBuffer *buffer, - const unsigned char fid, const int8_t value) -{ - int result; - SFSerializePackFieldInt8 *obj; - - if ((result=fast_buffer_check_inc_size(buffer, - sizeof(SFSerializePackFieldInt8))) != 0) - { - return result; - } - - obj = (SFSerializePackFieldInt8 *)(buffer->data + buffer->length); - obj->field.id = fid; - obj->field.type = sf_serialize_value_type_int8; - obj->value = value; - buffer->length += sizeof(SFSerializePackFieldInt8); - return 0; -} - -static inline int sf_serialize_pack_int16(FastBuffer *buffer, - const unsigned char fid, const int16_t value) -{ - int result; - SFSerializePackFieldInt16 *obj; - - if ((result=fast_buffer_check_inc_size(buffer, - sizeof(SFSerializePackFieldInt16))) != 0) - { - return result; - } - - obj = (SFSerializePackFieldInt16 *)(buffer->data + buffer->length); - obj->field.id = fid; - obj->field.type = sf_serialize_value_type_int16; - short2buff(value, obj->value); - buffer->length += sizeof(SFSerializePackFieldInt16); - return 0; -} - -static inline int sf_serialize_pack_int32(FastBuffer *buffer, - const unsigned char fid, const int32_t value) -{ - int result; - SFSerializePackFieldInt32 *obj; - - if ((result=fast_buffer_check_inc_size(buffer, - sizeof(SFSerializePackFieldInt32))) != 0) - { - return result; - } - - obj = (SFSerializePackFieldInt32 *)(buffer->data + buffer->length); - obj->field.id = fid; - obj->field.type = sf_serialize_value_type_int32; - int2buff(value, obj->value); - buffer->length += sizeof(SFSerializePackFieldInt32); - return 0; -} - -static inline int sf_serialize_pack_int64(FastBuffer *buffer, - const unsigned char fid, const int64_t value) -{ - int result; - SFSerializePackFieldInt64 *obj; - - if ((result=fast_buffer_check_inc_size(buffer, - sizeof(SFSerializePackFieldInt64))) != 0) - { - return result; - } - - obj = (SFSerializePackFieldInt64 *)(buffer->data + buffer->length); - obj->field.id = fid; - obj->field.type = sf_serialize_value_type_int64; - long2buff(value, obj->value); - buffer->length += sizeof(SFSerializePackFieldInt64); - return 0; -} - -#define SF_SERIALIZE_PACK_STRING(ps, value) \ - int2buff((value)->len, (ps)->len); \ - memcpy((ps)->str, (value)->str, (value)->len) - -#define SF_SERIALIZE_PACK_STRING_AND_MOVE_PTR(ps, value) \ - SF_SERIALIZE_PACK_STRING(ps, value); \ - ps = (SFSerializePackStringValue *)(((char *)ps) + sizeof( \ - SFSerializePackStringValue) + (value)->len) - -static inline int sf_serialize_pack_string(FastBuffer *buffer, - const unsigned char fid, const string_t *value) -{ - int result; - int length; - SFSerializePackFieldString *obj; - - length = sizeof(SFSerializePackFieldString) + value->len; - if ((result=fast_buffer_check_inc_size(buffer, length)) != 0) { - return result; - } - - obj = (SFSerializePackFieldString *)(buffer->data + buffer->length); - obj->field.id = fid; - obj->field.type = sf_serialize_value_type_string; - SF_SERIALIZE_PACK_STRING(&obj->value, value); - buffer->length += length; - return 0; -} - -static inline int sf_serialize_pack_int32_array(FastBuffer *buffer, - const unsigned char fid, const int32_t *array, const int count) -{ - int result; - int length; - SFSerializePackFieldArray *obj; - const int32_t *pn; - const int32_t *end; - char *ps; - - length = sizeof(SFSerializePackFieldArray) + count * 4; - if ((result=fast_buffer_check_inc_size(buffer, length)) != 0) { - return result; - } - - obj = (SFSerializePackFieldArray *)(buffer->data + buffer->length); - obj->field.id = fid; - obj->field.type = sf_serialize_value_type_int32_array; - int2buff(count, obj->value.count); - end = array + count; - for (pn=array, ps=obj->value.ptr; pnlength += length; - return 0; -} - -static inline int sf_serialize_pack_int64_array(FastBuffer *buffer, - const unsigned char fid, const int64_t *array, const int count) -{ - int result; - int length; - SFSerializePackFieldArray *obj; - const int64_t *pn; - const int64_t *end; - char *ps; - - length = sizeof(SFSerializePackFieldArray) + count * 8; - if ((result=fast_buffer_check_inc_size(buffer, length)) != 0) { - return result; - } - - obj = (SFSerializePackFieldArray *)(buffer->data + buffer->length); - obj->field.id = fid; - obj->field.type = sf_serialize_value_type_int64_array; - long2buff(count, obj->value.count); - end = array + count; - for (pn=array, ps=obj->value.ptr; pnlength += length; - return 0; -} - -static inline int sf_serialize_pack_map(FastBuffer *buffer, - const unsigned char fid, const key_value_pair_t *kv_pairs, - const int count) -{ - int result; - int length; - SFSerializePackFieldArray *obj; - const key_value_pair_t *pair; - const key_value_pair_t *end; - SFSerializePackStringValue *ps; - - length = sizeof(SFSerializePackFieldArray); - end = kv_pairs + count; - for (pair=kv_pairs; pairkey.len + pair->value.len; - } - - if ((result=fast_buffer_check_inc_size(buffer, length)) != 0) { - return result; - } - - obj = (SFSerializePackFieldArray *)(buffer->data + buffer->length); - obj->field.id = fid; - obj->field.type = sf_serialize_value_type_map; - long2buff(count, obj->value.count); - - ps = (SFSerializePackStringValue *)obj->value.ptr; - for (pair=kv_pairs; pairkey); - SF_SERIALIZE_PACK_STRING_AND_MOVE_PTR(ps, &pair->value); - } - buffer->length += length; - return 0; -} - -static inline void sf_serialize_pack_end(FastBuffer *buffer) -{ - SFSerializePackHeader *header; - int length; - int crc32; - - header = (SFSerializePackHeader *)buffer->data; - length = buffer->length - sizeof(SFSerializePackHeader); - crc32 = CRC32(header + 1, length); - int2buff(length, header->length); - int2buff(crc32, header->crc32); -} - -static inline void sf_serialize_iterator_init(SFSerializeIterator *it) -{ - memset(it, 0, sizeof(SFSerializeIterator)); -} - -static inline void sf_serialize_iterator_destroy(SFSerializeIterator *it) -{ - if (it->int_array.elts != NULL) { - free(it->int_array.elts); - it->int_array_alloc = 0; - } - - if (it->kv_array.kv_pairs != NULL) { - free(it->kv_array.kv_pairs); - it->kv_array_alloc = 0; - } -} - -int sf_serialize_unpack(SFSerializeIterator *it, const string_t *content); - -const SFSerializeFieldValue *sf_serialize_next(SFSerializeIterator *it); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/sf_serialize.c b/src/sf_serializer.c similarity index 67% rename from src/sf_serialize.c rename to src/sf_serializer.c index 7de0984..8c65709 100644 --- a/src/sf_serialize.c +++ b/src/sf_serializer.c @@ -25,7 +25,7 @@ #include #include "fastcommon/shared_func.h" #include "fastcommon/logger.h" -#include "sf_serialize.h" +#include "sf_serializer.h" #define FIELD_ID_AND_TYPE_FORMAT "fid: %d, type: %s" #define FIELD_ID_AND_TYPE_PARAMS it->field.fid, \ @@ -36,41 +36,41 @@ typedef struct { const char *name; int min_size; int elt_size; -} SFSerializeTypeConfig; +} SFSerializerTypeConfig; -static SFSerializeTypeConfig value_type_configs[SF_SERIALIZE_VALUE_TYPE_COUNT] = +static SFSerializerTypeConfig value_type_configs[SF_SERIALIZER_VALUE_TYPE_COUNT] = { - {"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)} + {"int8", sizeof(SFSerializerPackFieldInt8), 0}, + {"int16", sizeof(SFSerializerPackFieldInt16), 0}, + {"int32", sizeof(SFSerializerPackFieldInt32), 0}, + {"int64", sizeof(SFSerializerPackFieldInt64), 0}, + {"string", sizeof(SFSerializerPackStringValue), 0}, + {"int32_array", sizeof(SFSerializerPackFieldArray), 4}, + {"int64_array", sizeof(SFSerializerPackFieldArray), 8}, + {"map", sizeof(SFSerializerPackFieldArray), 2 * + sizeof(SFSerializerPackStringValue)} }; -int sf_serialize_unpack(SFSerializeIterator *it, const string_t *content) +int sf_serializer_unpack(SFSerializerIterator *it, const string_t *content) { - SFSerializePackHeader *header; + SFSerializerPackHeader *header; int length; int calc_crc32; int header_crc32; - if (content->len < sizeof(SFSerializePackHeader)) { + if (content->len < sizeof(SFSerializerPackHeader)) { snprintf(it->error_info, sizeof(it->error_info), "content length: %d is too small which < %d", - content->len, (int)sizeof(SFSerializePackHeader)); + content->len, (int)sizeof(SFSerializerPackHeader)); return EINVAL; } - header = (SFSerializePackHeader *)content->str; + header = (SFSerializerPackHeader *)content->str; length = buff2int(header->length); - if (content->len != length + sizeof(SFSerializePackHeader)) { + if (content->len != length + sizeof(SFSerializerPackHeader)) { snprintf(it->error_info, sizeof(it->error_info), "content length: %d != %d", content->len, - (int)(length + sizeof(SFSerializePackHeader))); + (int)(length + sizeof(SFSerializerPackHeader))); return EINVAL; } @@ -88,10 +88,10 @@ int sf_serialize_unpack(SFSerializeIterator *it, const string_t *content) return 0; } -static int check_field_type(SFSerializeIterator *it, - const int remain_len, const SFSerializeValueType type) +static int check_field_type(SFSerializerIterator *it, + const int remain_len, const SFSerializerValueType type) { - if (!(type >= 0 && type < SF_SERIALIZE_VALUE_TYPE_COUNT)) { + if (!(type >= 0 && type < SF_SERIALIZER_VALUE_TYPE_COUNT)) { snprintf(it->error_info, sizeof(it->error_info), "fid: %d, unknown type: %d", it->field.fid, type); return EINVAL; @@ -107,7 +107,7 @@ static int check_field_type(SFSerializeIterator *it, return 0; } -static inline int check_string_value(SFSerializeIterator *it, +static inline int check_string_value(SFSerializerIterator *it, const int remain_len, const string_t *s) { if (s->len < 0) { @@ -128,12 +128,12 @@ static inline int check_string_value(SFSerializeIterator *it, return 0; } -static inline int unpack_array_count(SFSerializeIterator *it, +static inline int unpack_array_count(SFSerializerIterator *it, const int remain_len, int *count) { int min_size; - *count = buff2int(((SFSerializePackFieldArray *)it->p)->value.count); + *count = buff2int(((SFSerializerPackFieldArray *)it->p)->value.count); if (*count < 0) { snprintf(it->error_info, sizeof(it->error_info), FIELD_ID_AND_TYPE_FORMAT", invalid array count: %d < 0", @@ -153,7 +153,7 @@ static inline int unpack_array_count(SFSerializeIterator *it, return 0; } -static int array_expand(SFSerializeIterator *it, void_array_t *array, +static int array_expand(SFSerializerIterator *it, void_array_t *array, const int elt_size, const int target_count, int *alloc_size) { int new_alloc; @@ -184,25 +184,25 @@ static int array_expand(SFSerializeIterator *it, void_array_t *array, return 0; } -static inline int unpack_string(SFSerializeIterator *it, const int remain_len, - SFSerializePackStringValue *input, string_t *output) +static inline int unpack_string(SFSerializerIterator *it, const int remain_len, + SFSerializerPackStringValue *input, string_t *output) { - if (remain_len < sizeof(SFSerializePackStringValue)) { + if (remain_len < 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, - remain_len, (int)sizeof(SFSerializePackStringValue)); + remain_len, (int)sizeof(SFSerializerPackStringValue)); return EINVAL; } output->len = buff2int(input->len); output->str = input->str; - it->p += sizeof(SFSerializePackStringValue) + output->len; + it->p += sizeof(SFSerializerPackStringValue) + output->len; return check_string_value(it, remain_len - - sizeof(SFSerializePackStringValue), output); + sizeof(SFSerializerPackStringValue), output); } -static int unpack_array(SFSerializeIterator *it, const int remain_len) +static int unpack_array(SFSerializerIterator *it, const int remain_len) { int result; int count; @@ -221,10 +221,10 @@ static int unpack_array(SFSerializeIterator *it, const int remain_len) } } - it->p += sizeof(SFSerializePackFieldArray); + it->p += sizeof(SFSerializerPackFieldArray); end = it->int_array.elts + count; for (pn=it->int_array.elts; pnfield.type == sf_serialize_value_type_int32_array) { + if (it->field.type == sf_serializer_value_type_int32_array) { *pn = buff2int(it->p); } else { *pn = buff2long(it->p); @@ -236,7 +236,7 @@ static int unpack_array(SFSerializeIterator *it, const int remain_len) return 0; } -static int unpack_map(SFSerializeIterator *it, const int remain_len) +static int unpack_map(SFSerializerIterator *it, const int remain_len) { int result; int count; @@ -256,17 +256,17 @@ static int unpack_map(SFSerializeIterator *it, const int remain_len) } } - it->p += sizeof(SFSerializePackFieldArray); + it->p += sizeof(SFSerializerPackFieldArray); end = it->kv_array.kv_pairs + count; for (pair=it->kv_array.kv_pairs; pairend - it->p, - (SFSerializePackStringValue *)it->p, + (SFSerializerPackStringValue *)it->p, &pair->key)) != 0) { return result; } if ((result=unpack_string(it, it->end - it->p, - (SFSerializePackStringValue *)it->p, + (SFSerializerPackStringValue *)it->p, &pair->value)) != 0) { return result; @@ -277,26 +277,26 @@ static int unpack_map(SFSerializeIterator *it, const int remain_len) return 0; } -const SFSerializeFieldValue *sf_serialize_next(SFSerializeIterator *it) +const SFSerializerFieldValue *sf_serializer_next(SFSerializerIterator *it) { int remain_len; - SFSerializePackFieldInfo *field; - SFSerializePackFieldString *fs; + SFSerializerPackFieldInfo *field; + SFSerializerPackFieldString *fs; remain_len = it->end - it->p; if (remain_len == 0) { return NULL; } - if (remain_len <= sizeof(SFSerializePackFieldInfo)) { + if (remain_len <= sizeof(SFSerializerPackFieldInfo)) { snprintf(it->error_info, sizeof(it->error_info), "remain length: %d is too small which <= %d", - remain_len, (int)sizeof(SFSerializePackFieldInfo)); + remain_len, (int)sizeof(SFSerializerPackFieldInfo)); it->error_no = EINVAL; return NULL; } - field = (SFSerializePackFieldInfo *)it->p; + field = (SFSerializerPackFieldInfo *)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) { @@ -304,50 +304,50 @@ const SFSerializeFieldValue *sf_serialize_next(SFSerializeIterator *it) } switch (field->type) { - case sf_serialize_value_type_int8: - it->field.value.n = ((SFSerializePackFieldInt8 *)it->p)->value; - it->p += sizeof(SFSerializePackFieldInt8); + case sf_serializer_value_type_int8: + it->field.value.n = ((SFSerializerPackFieldInt8 *)it->p)->value; + it->p += sizeof(SFSerializerPackFieldInt8); break; - case sf_serialize_value_type_int16: + case sf_serializer_value_type_int16: it->field.value.n = buff2short( - ((SFSerializePackFieldInt16 *) + ((SFSerializerPackFieldInt16 *) it->p)->value); - it->p += sizeof(SFSerializePackFieldInt16); + it->p += sizeof(SFSerializerPackFieldInt16); break; - case sf_serialize_value_type_int32: + case sf_serializer_value_type_int32: it->field.value.n = buff2int( - ((SFSerializePackFieldInt32 *) + ((SFSerializerPackFieldInt32 *) it->p)->value); - it->p += sizeof(SFSerializePackFieldInt32); + it->p += sizeof(SFSerializerPackFieldInt32); break; - case sf_serialize_value_type_int64: + case sf_serializer_value_type_int64: it->field.value.n = buff2long( - ((SFSerializePackFieldInt64 *) + ((SFSerializerPackFieldInt64 *) it->p)->value); - it->p += sizeof(SFSerializePackFieldInt64); + it->p += sizeof(SFSerializerPackFieldInt64); break; - case sf_serialize_value_type_string: - fs = (SFSerializePackFieldString *)it->p; - it->p += sizeof(SFSerializePackFieldInfo); + case sf_serializer_value_type_string: + fs = (SFSerializerPackFieldString *)it->p; + it->p += sizeof(SFSerializerPackFieldInfo); if ((it->error_no=unpack_string(it, remain_len - - sizeof(SFSerializePackFieldInfo), + sizeof(SFSerializerPackFieldInfo), &fs->value, &it->field.value.s)) != 0) { return NULL; } break; - case sf_serialize_value_type_int32_array: - case sf_serialize_value_type_int64_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( - SFSerializePackFieldArray))) != 0) + SFSerializerPackFieldArray))) != 0) { return NULL; } it->field.value.int_array = it->int_array; break; - case sf_serialize_value_type_map: + case sf_serializer_value_type_map: if ((it->error_no=unpack_map(it, remain_len - sizeof( - SFSerializePackFieldArray))) != 0) + SFSerializerPackFieldArray))) != 0) { return NULL; } diff --git a/src/sf_serializer.h b/src/sf_serializer.h new file mode 100644 index 0000000..d5965c0 --- /dev/null +++ b/src/sf_serializer.h @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2020 YuQing <384681@qq.com> + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +//sf_serializer.h + +#ifndef _SF_SERIALIZER_H +#define _SF_SERIALIZER_H + +#include "fastcommon/common_define.h" +#include "fastcommon/fast_buffer.h" +#include "fastcommon/hash.h" + +#define SF_SERIALIZER_VALUE_TYPE_COUNT 8 + +typedef enum { + sf_serializer_value_type_int8 = 0, + sf_serializer_value_type_int16, + sf_serializer_value_type_int32, + sf_serializer_value_type_int64, + sf_serializer_value_type_string, + sf_serializer_value_type_int32_array, + sf_serializer_value_type_int64_array, + sf_serializer_value_type_map +} SFSerializerValueType; + +typedef struct sf_serializer_pack_header { + char length[4]; + char crc32[4]; +} SFSerializerPackHeader; + +typedef struct sf_serializer_pack_field_info { + unsigned char id; + unsigned char type; +} SFSerializerPackFieldInfo; + +typedef struct sf_serializer_pack_field_int8 { + SFSerializerPackFieldInfo field; + char value; +} SFSerializerPackFieldInt8; + +typedef struct sf_serializer_pack_field_int16 { + SFSerializerPackFieldInfo field; + char value[2]; +} SFSerializerPackFieldInt16; + +typedef struct sf_serializer_pack_field_int32 { + SFSerializerPackFieldInfo field; + char value[4]; +} SFSerializerPackFieldInt32; + +typedef struct sf_serializer_pack_field_int64 { + SFSerializerPackFieldInfo field; + char value[8]; +} SFSerializerPackFieldInt64; + +typedef struct sf_serializer_pack_string_value { + char len[4]; + char str[0]; +} SFSerializerPackStringValue; + +typedef struct sf_serializer_pack_field_string { + SFSerializerPackFieldInfo field; + SFSerializerPackStringValue value; +} SFSerializerPackFieldString; + +typedef struct sf_serializer_pack_field_array { + SFSerializerPackFieldInfo field; + struct { + char count[4]; + char ptr[0]; + } value; +} SFSerializerPackFieldArray; + +typedef struct sf_serializer_field_value { + unsigned char fid; + SFSerializerValueType type; + union { + int64_t n; + string_t s; + int64_array_t int_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 + int int_array_alloc; + int kv_array_alloc; + SFSerializerFieldValue field; + int error_no; + char error_info[256]; +} SFSerializerIterator; + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void sf_serializer_pack_begin(FastBuffer *buffer) +{ + buffer->length = sizeof(SFSerializerPackHeader); +} + +static inline int sf_serializer_pack_int8(FastBuffer *buffer, + const unsigned char fid, const int8_t value) +{ + int result; + SFSerializerPackFieldInt8 *obj; + + if ((result=fast_buffer_check_inc_size(buffer, + sizeof(SFSerializerPackFieldInt8))) != 0) + { + return result; + } + + obj = (SFSerializerPackFieldInt8 *)(buffer->data + buffer->length); + obj->field.id = fid; + obj->field.type = sf_serializer_value_type_int8; + obj->value = value; + buffer->length += sizeof(SFSerializerPackFieldInt8); + return 0; +} + +static inline int sf_serializer_pack_int16(FastBuffer *buffer, + const unsigned char fid, const int16_t value) +{ + int result; + SFSerializerPackFieldInt16 *obj; + + if ((result=fast_buffer_check_inc_size(buffer, + sizeof(SFSerializerPackFieldInt16))) != 0) + { + return result; + } + + obj = (SFSerializerPackFieldInt16 *)(buffer->data + buffer->length); + obj->field.id = fid; + obj->field.type = sf_serializer_value_type_int16; + short2buff(value, obj->value); + buffer->length += sizeof(SFSerializerPackFieldInt16); + return 0; +} + +static inline int sf_serializer_pack_int32(FastBuffer *buffer, + const unsigned char fid, const int32_t value) +{ + int result; + SFSerializerPackFieldInt32 *obj; + + if ((result=fast_buffer_check_inc_size(buffer, + sizeof(SFSerializerPackFieldInt32))) != 0) + { + return result; + } + + obj = (SFSerializerPackFieldInt32 *)(buffer->data + buffer->length); + obj->field.id = fid; + obj->field.type = sf_serializer_value_type_int32; + int2buff(value, obj->value); + buffer->length += sizeof(SFSerializerPackFieldInt32); + return 0; +} + +static inline int sf_serializer_pack_int64(FastBuffer *buffer, + const unsigned char fid, const int64_t value) +{ + int result; + SFSerializerPackFieldInt64 *obj; + + if ((result=fast_buffer_check_inc_size(buffer, + sizeof(SFSerializerPackFieldInt64))) != 0) + { + return result; + } + + obj = (SFSerializerPackFieldInt64 *)(buffer->data + buffer->length); + obj->field.id = fid; + obj->field.type = sf_serializer_value_type_int64; + long2buff(value, obj->value); + buffer->length += sizeof(SFSerializerPackFieldInt64); + return 0; +} + +#define SF_SERIALIZER_PACK_STRING(ps, value) \ + 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) + +static inline int sf_serializer_pack_string(FastBuffer *buffer, + const unsigned char fid, const string_t *value) +{ + int result; + int length; + SFSerializerPackFieldString *obj; + + length = sizeof(SFSerializerPackFieldString) + value->len; + if ((result=fast_buffer_check_inc_size(buffer, length)) != 0) { + return result; + } + + obj = (SFSerializerPackFieldString *)(buffer->data + buffer->length); + obj->field.id = fid; + obj->field.type = sf_serializer_value_type_string; + SF_SERIALIZER_PACK_STRING(&obj->value, value); + buffer->length += length; + return 0; +} + +static inline int sf_serializer_pack_int32_array(FastBuffer *buffer, + const unsigned char fid, const int32_t *array, const int count) +{ + int result; + int length; + SFSerializerPackFieldArray *obj; + const int32_t *pn; + const int32_t *end; + char *ps; + + length = sizeof(SFSerializerPackFieldArray) + count * 4; + 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_int32_array; + int2buff(count, obj->value.count); + end = array + count; + for (pn=array, ps=obj->value.ptr; pnlength += length; + return 0; +} + +static inline int sf_serializer_pack_int64_array(FastBuffer *buffer, + const unsigned char fid, const int64_t *array, const int count) +{ + int result; + int length; + SFSerializerPackFieldArray *obj; + const int64_t *pn; + const int64_t *end; + char *ps; + + length = sizeof(SFSerializerPackFieldArray) + count * 8; + 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_int64_array; + long2buff(count, obj->value.count); + end = array + count; + for (pn=array, ps=obj->value.ptr; pnlength += 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) +{ + int result; + int length; + SFSerializerPackFieldArray *obj; + const key_value_pair_t *pair; + const key_value_pair_t *end; + SFSerializerPackStringValue *ps; + + length = sizeof(SFSerializerPackFieldArray); + end = kv_pairs + count; + for (pair=kv_pairs; pairkey.len + pair->value.len; + } + + 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_map; + long2buff(count, obj->value.count); + + ps = (SFSerializerPackStringValue *)obj->value.ptr; + for (pair=kv_pairs; pairkey); + SF_SERIALIZER_PACK_STRING_AND_MOVE_PTR(ps, &pair->value); + } + buffer->length += length; + return 0; +} + +static inline void sf_serializer_pack_end(FastBuffer *buffer) +{ + SFSerializerPackHeader *header; + int length; + int crc32; + + header = (SFSerializerPackHeader *)buffer->data; + length = buffer->length - sizeof(SFSerializerPackHeader); + crc32 = CRC32(header + 1, length); + int2buff(length, header->length); + int2buff(crc32, header->crc32); +} + +static inline void sf_serializer_iterator_init(SFSerializerIterator *it) +{ + memset(it, 0, sizeof(SFSerializerIterator)); +} + +static inline void sf_serializer_iterator_destroy(SFSerializerIterator *it) +{ + if (it->int_array.elts != NULL) { + free(it->int_array.elts); + it->int_array_alloc = 0; + } + + if (it->kv_array.kv_pairs != NULL) { + free(it->kv_array.kv_pairs); + it->kv_array_alloc = 0; + } +} + +int sf_serializer_unpack(SFSerializerIterator *it, const string_t *content); + +const SFSerializerFieldValue *sf_serializer_next(SFSerializerIterator *it); + +#ifdef __cplusplus +} +#endif + +#endif