rename sf_serialize.[hc] to sf_serializer.[hc]
parent
88a0f0a267
commit
d79310674e
|
|
@ -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 \
|
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_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 sf_binlog_index.h
|
sf_serializer.h sf_binlog_index.h
|
||||||
|
|
||||||
IDEMP_SERVER_HEADER = idempotency/server/server_types.h \
|
IDEMP_SERVER_HEADER = idempotency/server/server_types.h \
|
||||||
idempotency/server/server_channel.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_func.lo sf_util.lo sf_configs.lo sf_proto.lo \
|
||||||
sf_binlog_writer.lo sf_sharding_htable.lo \
|
sf_binlog_writer.lo sf_sharding_htable.lo \
|
||||||
sf_cluster_cfg.lo sf_connection_manager.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/server_channel.lo \
|
||||||
idempotency/server/request_htable.lo \
|
idempotency/server/request_htable.lo \
|
||||||
idempotency/server/channel_htable.lo \
|
idempotency/server/channel_htable.lo \
|
||||||
|
|
|
||||||
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//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; pn<end; pn++, ps+=4) {
|
|
||||||
int2buff(*pn, ps);
|
|
||||||
}
|
|
||||||
buffer->length += 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; pn<end; pn++, ps+=8) {
|
|
||||||
int2buff(*pn, ps);
|
|
||||||
}
|
|
||||||
buffer->length += 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; pair<end; pair++) {
|
|
||||||
length += sizeof(SFSerializePackStringValue) * 2 +
|
|
||||||
pair->key.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; pair<end; pair++) {
|
|
||||||
SF_SERIALIZE_PACK_STRING_AND_MOVE_PTR(ps, &pair->key);
|
|
||||||
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
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "fastcommon/shared_func.h"
|
#include "fastcommon/shared_func.h"
|
||||||
#include "fastcommon/logger.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_FORMAT "fid: %d, type: %s"
|
||||||
#define FIELD_ID_AND_TYPE_PARAMS it->field.fid, \
|
#define FIELD_ID_AND_TYPE_PARAMS it->field.fid, \
|
||||||
|
|
@ -36,41 +36,41 @@ typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
int min_size;
|
int min_size;
|
||||||
int elt_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},
|
{"int8", sizeof(SFSerializerPackFieldInt8), 0},
|
||||||
{"int16", sizeof(SFSerializePackFieldInt16), 0},
|
{"int16", sizeof(SFSerializerPackFieldInt16), 0},
|
||||||
{"int32", sizeof(SFSerializePackFieldInt32), 0},
|
{"int32", sizeof(SFSerializerPackFieldInt32), 0},
|
||||||
{"int64", sizeof(SFSerializePackFieldInt64), 0},
|
{"int64", sizeof(SFSerializerPackFieldInt64), 0},
|
||||||
{"string", sizeof(SFSerializePackStringValue), 0},
|
{"string", sizeof(SFSerializerPackStringValue), 0},
|
||||||
{"int32_array", sizeof(SFSerializePackFieldArray), 4},
|
{"int32_array", sizeof(SFSerializerPackFieldArray), 4},
|
||||||
{"int64_array", sizeof(SFSerializePackFieldArray), 8},
|
{"int64_array", sizeof(SFSerializerPackFieldArray), 8},
|
||||||
{"map", sizeof(SFSerializePackFieldArray), 2 *
|
{"map", sizeof(SFSerializerPackFieldArray), 2 *
|
||||||
sizeof(SFSerializePackStringValue)}
|
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 length;
|
||||||
int calc_crc32;
|
int calc_crc32;
|
||||||
int header_crc32;
|
int header_crc32;
|
||||||
|
|
||||||
if (content->len < sizeof(SFSerializePackHeader)) {
|
if (content->len < sizeof(SFSerializerPackHeader)) {
|
||||||
snprintf(it->error_info, sizeof(it->error_info),
|
snprintf(it->error_info, sizeof(it->error_info),
|
||||||
"content length: %d is too small which < %d",
|
"content length: %d is too small which < %d",
|
||||||
content->len, (int)sizeof(SFSerializePackHeader));
|
content->len, (int)sizeof(SFSerializerPackHeader));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
header = (SFSerializePackHeader *)content->str;
|
header = (SFSerializerPackHeader *)content->str;
|
||||||
length = buff2int(header->length);
|
length = buff2int(header->length);
|
||||||
if (content->len != length + sizeof(SFSerializePackHeader)) {
|
if (content->len != length + sizeof(SFSerializerPackHeader)) {
|
||||||
snprintf(it->error_info, sizeof(it->error_info),
|
snprintf(it->error_info, sizeof(it->error_info),
|
||||||
"content length: %d != %d", content->len,
|
"content length: %d != %d", content->len,
|
||||||
(int)(length + sizeof(SFSerializePackHeader)));
|
(int)(length + sizeof(SFSerializerPackHeader)));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,10 +88,10 @@ int sf_serialize_unpack(SFSerializeIterator *it, const string_t *content)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_field_type(SFSerializeIterator *it,
|
static int check_field_type(SFSerializerIterator *it,
|
||||||
const int remain_len, const SFSerializeValueType type)
|
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),
|
snprintf(it->error_info, sizeof(it->error_info),
|
||||||
"fid: %d, unknown type: %d", it->field.fid, type);
|
"fid: %d, unknown type: %d", it->field.fid, type);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
@ -107,7 +107,7 @@ static int check_field_type(SFSerializeIterator *it,
|
||||||
return 0;
|
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)
|
const int remain_len, const string_t *s)
|
||||||
{
|
{
|
||||||
if (s->len < 0) {
|
if (s->len < 0) {
|
||||||
|
|
@ -128,12 +128,12 @@ static inline int check_string_value(SFSerializeIterator *it,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int unpack_array_count(SFSerializeIterator *it,
|
static inline int unpack_array_count(SFSerializerIterator *it,
|
||||||
const int remain_len, int *count)
|
const int remain_len, int *count)
|
||||||
{
|
{
|
||||||
int min_size;
|
int min_size;
|
||||||
|
|
||||||
*count = buff2int(((SFSerializePackFieldArray *)it->p)->value.count);
|
*count = buff2int(((SFSerializerPackFieldArray *)it->p)->value.count);
|
||||||
if (*count < 0) {
|
if (*count < 0) {
|
||||||
snprintf(it->error_info, sizeof(it->error_info),
|
snprintf(it->error_info, sizeof(it->error_info),
|
||||||
FIELD_ID_AND_TYPE_FORMAT", invalid array count: %d < 0",
|
FIELD_ID_AND_TYPE_FORMAT", invalid array count: %d < 0",
|
||||||
|
|
@ -153,7 +153,7 @@ static inline int unpack_array_count(SFSerializeIterator *it,
|
||||||
return 0;
|
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)
|
const int elt_size, const int target_count, int *alloc_size)
|
||||||
{
|
{
|
||||||
int new_alloc;
|
int new_alloc;
|
||||||
|
|
@ -184,25 +184,25 @@ static int array_expand(SFSerializeIterator *it, void_array_t *array,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int unpack_string(SFSerializeIterator *it, const int remain_len,
|
static inline int unpack_string(SFSerializerIterator *it, const int remain_len,
|
||||||
SFSerializePackStringValue *input, string_t *output)
|
SFSerializerPackStringValue *input, string_t *output)
|
||||||
{
|
{
|
||||||
if (remain_len < sizeof(SFSerializePackStringValue)) {
|
if (remain_len < sizeof(SFSerializerPackStringValue)) {
|
||||||
snprintf(it->error_info, sizeof(it->error_info),
|
snprintf(it->error_info, sizeof(it->error_info),
|
||||||
FIELD_ID_AND_TYPE_FORMAT", remain length: %d "
|
FIELD_ID_AND_TYPE_FORMAT", remain length: %d "
|
||||||
"is too small < %d", FIELD_ID_AND_TYPE_PARAMS,
|
"is too small < %d", FIELD_ID_AND_TYPE_PARAMS,
|
||||||
remain_len, (int)sizeof(SFSerializePackStringValue));
|
remain_len, (int)sizeof(SFSerializerPackStringValue));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
output->len = buff2int(input->len);
|
output->len = buff2int(input->len);
|
||||||
output->str = input->str;
|
output->str = input->str;
|
||||||
it->p += sizeof(SFSerializePackStringValue) + output->len;
|
it->p += sizeof(SFSerializerPackStringValue) + output->len;
|
||||||
return check_string_value(it, remain_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 result;
|
||||||
int count;
|
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;
|
end = it->int_array.elts + count;
|
||||||
for (pn=it->int_array.elts; pn<end; pn++) {
|
for (pn=it->int_array.elts; pn<end; pn++) {
|
||||||
if (it->field.type == sf_serialize_value_type_int32_array) {
|
if (it->field.type == sf_serializer_value_type_int32_array) {
|
||||||
*pn = buff2int(it->p);
|
*pn = buff2int(it->p);
|
||||||
} else {
|
} else {
|
||||||
*pn = buff2long(it->p);
|
*pn = buff2long(it->p);
|
||||||
|
|
@ -236,7 +236,7 @@ static int unpack_array(SFSerializeIterator *it, const int remain_len)
|
||||||
return 0;
|
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 result;
|
||||||
int count;
|
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;
|
end = it->kv_array.kv_pairs + count;
|
||||||
for (pair=it->kv_array.kv_pairs; pair<end; pair++) {
|
for (pair=it->kv_array.kv_pairs; pair<end; pair++) {
|
||||||
if ((result=unpack_string(it, it->end - it->p,
|
if ((result=unpack_string(it, it->end - it->p,
|
||||||
(SFSerializePackStringValue *)it->p,
|
(SFSerializerPackStringValue *)it->p,
|
||||||
&pair->key)) != 0)
|
&pair->key)) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if ((result=unpack_string(it, it->end - it->p,
|
if ((result=unpack_string(it, it->end - it->p,
|
||||||
(SFSerializePackStringValue *)it->p,
|
(SFSerializerPackStringValue *)it->p,
|
||||||
&pair->value)) != 0)
|
&pair->value)) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -277,26 +277,26 @@ static int unpack_map(SFSerializeIterator *it, const int remain_len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SFSerializeFieldValue *sf_serialize_next(SFSerializeIterator *it)
|
const SFSerializerFieldValue *sf_serializer_next(SFSerializerIterator *it)
|
||||||
{
|
{
|
||||||
int remain_len;
|
int remain_len;
|
||||||
SFSerializePackFieldInfo *field;
|
SFSerializerPackFieldInfo *field;
|
||||||
SFSerializePackFieldString *fs;
|
SFSerializerPackFieldString *fs;
|
||||||
|
|
||||||
remain_len = it->end - it->p;
|
remain_len = it->end - it->p;
|
||||||
if (remain_len == 0) {
|
if (remain_len == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remain_len <= sizeof(SFSerializePackFieldInfo)) {
|
if (remain_len <= sizeof(SFSerializerPackFieldInfo)) {
|
||||||
snprintf(it->error_info, sizeof(it->error_info),
|
snprintf(it->error_info, sizeof(it->error_info),
|
||||||
"remain length: %d is too small which <= %d",
|
"remain length: %d is too small which <= %d",
|
||||||
remain_len, (int)sizeof(SFSerializePackFieldInfo));
|
remain_len, (int)sizeof(SFSerializerPackFieldInfo));
|
||||||
it->error_no = EINVAL;
|
it->error_no = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
field = (SFSerializePackFieldInfo *)it->p;
|
field = (SFSerializerPackFieldInfo *)it->p;
|
||||||
it->field.fid = field->id;
|
it->field.fid = field->id;
|
||||||
it->field.type = field->type;
|
it->field.type = field->type;
|
||||||
if ((it->error_no=check_field_type(it, remain_len, field->type)) != 0) {
|
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) {
|
switch (field->type) {
|
||||||
case sf_serialize_value_type_int8:
|
case sf_serializer_value_type_int8:
|
||||||
it->field.value.n = ((SFSerializePackFieldInt8 *)it->p)->value;
|
it->field.value.n = ((SFSerializerPackFieldInt8 *)it->p)->value;
|
||||||
it->p += sizeof(SFSerializePackFieldInt8);
|
it->p += sizeof(SFSerializerPackFieldInt8);
|
||||||
break;
|
break;
|
||||||
case sf_serialize_value_type_int16:
|
case sf_serializer_value_type_int16:
|
||||||
it->field.value.n = buff2short(
|
it->field.value.n = buff2short(
|
||||||
((SFSerializePackFieldInt16 *)
|
((SFSerializerPackFieldInt16 *)
|
||||||
it->p)->value);
|
it->p)->value);
|
||||||
it->p += sizeof(SFSerializePackFieldInt16);
|
it->p += sizeof(SFSerializerPackFieldInt16);
|
||||||
break;
|
break;
|
||||||
case sf_serialize_value_type_int32:
|
case sf_serializer_value_type_int32:
|
||||||
it->field.value.n = buff2int(
|
it->field.value.n = buff2int(
|
||||||
((SFSerializePackFieldInt32 *)
|
((SFSerializerPackFieldInt32 *)
|
||||||
it->p)->value);
|
it->p)->value);
|
||||||
it->p += sizeof(SFSerializePackFieldInt32);
|
it->p += sizeof(SFSerializerPackFieldInt32);
|
||||||
break;
|
break;
|
||||||
case sf_serialize_value_type_int64:
|
case sf_serializer_value_type_int64:
|
||||||
it->field.value.n = buff2long(
|
it->field.value.n = buff2long(
|
||||||
((SFSerializePackFieldInt64 *)
|
((SFSerializerPackFieldInt64 *)
|
||||||
it->p)->value);
|
it->p)->value);
|
||||||
it->p += sizeof(SFSerializePackFieldInt64);
|
it->p += sizeof(SFSerializerPackFieldInt64);
|
||||||
break;
|
break;
|
||||||
case sf_serialize_value_type_string:
|
case sf_serializer_value_type_string:
|
||||||
fs = (SFSerializePackFieldString *)it->p;
|
fs = (SFSerializerPackFieldString *)it->p;
|
||||||
it->p += sizeof(SFSerializePackFieldInfo);
|
it->p += sizeof(SFSerializerPackFieldInfo);
|
||||||
if ((it->error_no=unpack_string(it, remain_len -
|
if ((it->error_no=unpack_string(it, remain_len -
|
||||||
sizeof(SFSerializePackFieldInfo),
|
sizeof(SFSerializerPackFieldInfo),
|
||||||
&fs->value, &it->field.value.s)) != 0)
|
&fs->value, &it->field.value.s)) != 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case sf_serialize_value_type_int32_array:
|
case sf_serializer_value_type_int32_array:
|
||||||
case sf_serialize_value_type_int64_array:
|
case sf_serializer_value_type_int64_array:
|
||||||
if ((it->error_no=unpack_array(it, remain_len - sizeof(
|
if ((it->error_no=unpack_array(it, remain_len - sizeof(
|
||||||
SFSerializePackFieldArray))) != 0)
|
SFSerializerPackFieldArray))) != 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
it->field.value.int_array = it->int_array;
|
it->field.value.int_array = it->int_array;
|
||||||
break;
|
break;
|
||||||
case sf_serialize_value_type_map:
|
case sf_serializer_value_type_map:
|
||||||
if ((it->error_no=unpack_map(it, remain_len - sizeof(
|
if ((it->error_no=unpack_map(it, remain_len - sizeof(
|
||||||
SFSerializePackFieldArray))) != 0)
|
SFSerializerPackFieldArray))) != 0)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//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; pn<end; pn++, ps+=4) {
|
||||||
|
int2buff(*pn, ps);
|
||||||
|
}
|
||||||
|
buffer->length += 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; pn<end; pn++, ps+=8) {
|
||||||
|
int2buff(*pn, ps);
|
||||||
|
}
|
||||||
|
buffer->length += 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; pair<end; pair++) {
|
||||||
|
length += sizeof(SFSerializerPackStringValue) * 2 +
|
||||||
|
pair->key.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; pair<end; pair++) {
|
||||||
|
SF_SERIALIZER_PACK_STRING_AND_MOVE_PTR(ps, &pair->key);
|
||||||
|
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
|
||||||
Loading…
Reference in New Issue