From 186d41fafedb591b6e2b876b4942aedd1caac6f7 Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Thu, 19 Aug 2021 16:49:07 +0800 Subject: [PATCH] add files: sf_serialize.[hc] --- src/Makefile.in | 4 +- src/sf_serialize.c | 28 ++++ src/sf_serialize.h | 336 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 367 insertions(+), 1 deletion(-) create mode 100644 src/sf_serialize.c create mode 100644 src/sf_serialize.h diff --git a/src/Makefile.in b/src/Makefile.in index a4979c5..1d73cbf 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -7,7 +7,8 @@ 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_cluster_cfg.h sf_sharding_htable.h sf_connection_manager.h \ + sf_serialize.h IDEMP_SERVER_HEADER = idempotency/server/server_types.h \ idempotency/server/server_channel.h \ @@ -26,6 +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 \ idempotency/server/server_channel.lo \ idempotency/server/request_htable.lo \ idempotency/server/channel_htable.lo \ diff --git a/src/sf_serialize.c b/src/sf_serialize.c new file mode 100644 index 0000000..84c10a8 --- /dev/null +++ b/src/sf_serialize.c @@ -0,0 +1,28 @@ +/* + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fastcommon/shared_func.h" +#include "fastcommon/logger.h" +#include "sf_serialize.h" diff --git a/src/sf_serialize.h b/src/sf_serialize.h new file mode 100644 index 0000000..bf61039 --- /dev/null +++ b/src/sf_serialize.h @@ -0,0 +1,336 @@ +/* + * 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" + +typedef enum { + sf_serialize_value_type_int8 = 1, + 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; + +#define SF_SERIALIZE_PACK_HEADER_SIZE sizeof(SFSerializePackHeader) + +typedef struct sf_serialize_iterator { + const char *p; + int64_array_t int_array; + key_value_array_t kv_array; +} SFSerializeIterator; + +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; + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void sf_serialize_pack_begin(FastBuffer *buffer) +{ + buffer->length = SF_SERIALIZE_PACK_HEADER_SIZE; +} + +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); +} + +int sf_serialize_iterator_init(SFSerializeIterator *it); + +void sf_serialize_iterator_destroy(SFSerializeIterator *it); + +int sf_serialize_unpack(SFSerializeIterator *it, const string_t *content); + +int sf_serialize_next(SFSerializeIterator *it, SFSerializeFieldValue *field); + +#ifdef __cplusplus +} +#endif + +#endif