sf_serialize_unpack integer and string impl

storage_engine
YuQing 2021-08-19 21:05:42 +08:00
parent 186d41fafe
commit c529c5ab8c
2 changed files with 202 additions and 9 deletions

View File

@ -26,3 +26,176 @@
#include "fastcommon/shared_func.h" #include "fastcommon/shared_func.h"
#include "fastcommon/logger.h" #include "fastcommon/logger.h"
#include "sf_serialize.h" #include "sf_serialize.h"
int sf_serialize_unpack(SFSerializeIterator *it, const string_t *content)
{
SFSerializePackHeader *header;
int length;
int calc_crc32;
int header_crc32;
if (content->len < sizeof(SFSerializePackHeader)) {
snprintf(it->error_info, sizeof(it->error_info),
"content length: %d is too small which < %d",
content->len, (int)sizeof(SFSerializePackHeader));
return EINVAL;
}
header = (SFSerializePackHeader *)content->str;
length = buff2int(header->length);
if (content->len != length + sizeof(SFSerializePackHeader)) {
snprintf(it->error_info, sizeof(it->error_info),
"content length: %d != %d", content->len,
(int)(length + sizeof(SFSerializePackHeader)));
return EINVAL;
}
calc_crc32 = CRC32(header + 1, length);
header_crc32 = buff2int(header->crc32);
if (header_crc32 != calc_crc32) {
snprintf(it->error_info, sizeof(it->error_info),
"header crc32: %d != calculated: %d",
header_crc32, calc_crc32);
return EINVAL;
}
it->p = (const char *)(header + 1);
it->end = content->str + content->len;
return 0;
}
static int check_field_type(SFSerializeIterator *it,
const int remain_len, const SFSerializeValueType type)
{
int min_size;
switch (type) {
case sf_serialize_value_type_int8:
min_size = sizeof(SFSerializePackFieldInt8);
break;
case sf_serialize_value_type_int16:
min_size = sizeof(SFSerializePackFieldInt16);
break;
case sf_serialize_value_type_int32:
min_size = sizeof(SFSerializePackFieldInt32);
break;
case sf_serialize_value_type_int64:
min_size = sizeof(SFSerializePackFieldInt64);
break;
case sf_serialize_value_type_string:
min_size = sizeof(SFSerializePackFieldString);
break;
case sf_serialize_value_type_int32_array:
case sf_serialize_value_type_int64_array:
case sf_serialize_value_type_map:
min_size = sizeof(SFSerializePackFieldArray);
break;
default:
snprintf(it->error_info, sizeof(it->error_info),
"unknown type: %d", type);
return EINVAL;
}
if (remain_len < min_size) {
snprintf(it->error_info, sizeof(it->error_info),
"remain length: %d is too small which < %d",
remain_len, min_size);
return EINVAL;
}
return 0;
}
static inline int check_string_value(SFSerializeIterator *it,
const int remain_len, const string_t *s)
{
if (s->len < 0) {
snprintf(it->error_info, sizeof(it->error_info),
"invalid string length: %d < 0", s->len);
return EINVAL;
}
if (s->len > remain_len) {
snprintf(it->error_info, sizeof(it->error_info),
"string length: %d is too large > remain length: %d",
s->len, remain_len);
return EINVAL;
}
return 0;
}
const SFSerializeFieldValue *sf_serialize_next(SFSerializeIterator *it)
{
int remain_len;
SFSerializePackFieldInfo *field;
SFSerializePackFieldString *fs;
remain_len = it->end - it->p;
if (remain_len == 0) {
return NULL;
}
if (remain_len <= sizeof(SFSerializePackFieldInfo)) {
snprintf(it->error_info, sizeof(it->error_info),
"remain length: %d is too small which <= %d",
remain_len, (int)sizeof(SFSerializePackFieldInfo));
it->error_no = EINVAL;
return NULL;
}
field = (SFSerializePackFieldInfo *)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) {
return NULL;
}
switch (field->type) {
case sf_serialize_value_type_int8:
it->field.value.n = ((SFSerializePackFieldInt8 *)it->p)->value;
it->p += sizeof(SFSerializePackFieldInt8);
break;
case sf_serialize_value_type_int16:
it->field.value.n = buff2short(
((SFSerializePackFieldInt16 *)
it->p)->value);
it->p += sizeof(SFSerializePackFieldInt16);
break;
case sf_serialize_value_type_int32:
it->field.value.n = buff2int(
((SFSerializePackFieldInt32 *)
it->p)->value);
it->p += sizeof(SFSerializePackFieldInt32);
break;
case sf_serialize_value_type_int64:
it->field.value.n = buff2long(
((SFSerializePackFieldInt64 *)
it->p)->value);
it->p += sizeof(SFSerializePackFieldInt64);
break;
case sf_serialize_value_type_string:
fs = (SFSerializePackFieldString *)it->p;
it->field.value.s.len = buff2int(fs->value.len);
it->field.value.s.str = fs->value.str;
if ((it->error_no=check_string_value(it, remain_len -
sizeof(SFSerializePackFieldString),
&it->field.value.s)) != 0)
{
return NULL;
}
it->p += sizeof(SFSerializePackFieldString) +
it->field.value.s.len;
break;
case sf_serialize_value_type_int32_array:
case sf_serialize_value_type_int64_array:
case sf_serialize_value_type_map:
default:
snprintf(it->error_info, sizeof(it->error_info),
"unknown type: %d", field->type);
it->error_no = EINVAL;
return NULL;
}
return &it->field;
}

View File

@ -83,12 +83,6 @@ typedef struct sf_serialize_pack_field_array {
#define SF_SERIALIZE_PACK_HEADER_SIZE sizeof(SFSerializePackHeader) #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 { typedef struct sf_serialize_field_value {
unsigned char fid; unsigned char fid;
SFSerializeValueType type; SFSerializeValueType type;
@ -100,6 +94,18 @@ typedef struct sf_serialize_field_value {
} value; } value;
} SFSerializeFieldValue; } SFSerializeFieldValue;
typedef struct sf_serialize_iterator {
const char *p;
const char *end;
int64_array_t int_array;
key_value_array_t kv_array;
int int_array_alloc;
int kv_array_alloc;
SFSerializeFieldValue field;
int error_no;
char error_info[256];
} SFSerializeIterator;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -321,13 +327,27 @@ static inline void sf_serialize_pack_end(FastBuffer *buffer)
int2buff(crc32, header->crc32); int2buff(crc32, header->crc32);
} }
int sf_serialize_iterator_init(SFSerializeIterator *it); static inline void sf_serialize_iterator_init(SFSerializeIterator *it)
{
memset(it, 0, sizeof(SFSerializeIterator));
}
void sf_serialize_iterator_destroy(SFSerializeIterator *it); static inline void sf_serialize_iterator_destroy(SFSerializeIterator *it)
{
if (it->int_array.values != NULL) {
free(it->int_array.values);
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); int sf_serialize_unpack(SFSerializeIterator *it, const string_t *content);
int sf_serialize_next(SFSerializeIterator *it, SFSerializeFieldValue *field); const SFSerializeFieldValue *sf_serialize_next(SFSerializeIterator *it);
#ifdef __cplusplus #ifdef __cplusplus
} }