sf_serializer.[hc]: support string array
parent
fd9d59dbd2
commit
e35a3ca104
|
|
@ -49,6 +49,8 @@ static SFSerializerTypeConfig value_type_configs[SF_SERIALIZER_VALUE_TYPE_COUNT]
|
||||||
{"int16_array", sizeof(SFSerializerPackFieldArray), 2},
|
{"int16_array", sizeof(SFSerializerPackFieldArray), 2},
|
||||||
{"int32_array", sizeof(SFSerializerPackFieldArray), 4},
|
{"int32_array", sizeof(SFSerializerPackFieldArray), 4},
|
||||||
{"int64_array", sizeof(SFSerializerPackFieldArray), 8},
|
{"int64_array", sizeof(SFSerializerPackFieldArray), 8},
|
||||||
|
{"string_array", sizeof(SFSerializerPackFieldArray),
|
||||||
|
sizeof(SFSerializerPackStringValue)},
|
||||||
{"map", sizeof(SFSerializerPackFieldArray), 2 *
|
{"map", sizeof(SFSerializerPackFieldArray), 2 *
|
||||||
sizeof(SFSerializerPackStringValue)}
|
sizeof(SFSerializerPackStringValue)}
|
||||||
};
|
};
|
||||||
|
|
@ -144,11 +146,11 @@ static inline int unpack_array_count(SFSerializerIterator *it,
|
||||||
}
|
}
|
||||||
|
|
||||||
min_size = value_type_configs[it->field.type].elt_size * (*count);
|
min_size = value_type_configs[it->field.type].elt_size * (*count);
|
||||||
if (min_size > remain_len) {
|
if (remain_len < min_size) {
|
||||||
snprintf(it->error_info, sizeof(it->error_info),
|
snprintf(it->error_info, sizeof(it->error_info),
|
||||||
FIELD_ID_AND_TYPE_FORMAT", array min bytes: %d is "
|
FIELD_ID_AND_TYPE_FORMAT", remain length: %d is too "
|
||||||
"too large > remain: %d", FIELD_ID_AND_TYPE_PARAMS,
|
"small < array min bytes: %d", FIELD_ID_AND_TYPE_PARAMS,
|
||||||
min_size, remain_len);
|
remain_len, min_size);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -204,7 +206,7 @@ static inline int unpack_string(SFSerializerIterator *it, const int remain_len,
|
||||||
sizeof(SFSerializerPackStringValue), output);
|
sizeof(SFSerializerPackStringValue), output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int unpack_array(SFSerializerIterator *it, const int remain_len)
|
static int unpack_integer_array(SFSerializerIterator *it, const int remain_len)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
int count;
|
int count;
|
||||||
|
|
@ -247,6 +249,40 @@ static int unpack_array(SFSerializerIterator *it, const int remain_len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int unpack_string_array(SFSerializerIterator *it, const int remain_len)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int count;
|
||||||
|
string_t *str;
|
||||||
|
string_t *end;
|
||||||
|
|
||||||
|
if ((result=unpack_array_count(it, remain_len, &count)) != 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count > it->str_array_alloc) {
|
||||||
|
if ((result=array_expand(it, (void_array_t *)&it->str_array,
|
||||||
|
sizeof(string_t), count, &it->str_array_alloc)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it->p += sizeof(SFSerializerPackFieldArray);
|
||||||
|
end = it->str_array.strings + count;
|
||||||
|
for (str=it->str_array.strings; str<end; str++) {
|
||||||
|
if ((result=unpack_string(it, it->end - it->p,
|
||||||
|
(SFSerializerPackStringValue *)
|
||||||
|
it->p, str)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it->str_array.count = count;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int unpack_map(SFSerializerIterator *it, const int remain_len)
|
static int unpack_map(SFSerializerIterator *it, const int remain_len)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
@ -351,13 +387,21 @@ const SFSerializerFieldValue *sf_serializer_next(SFSerializerIterator *it)
|
||||||
case sf_serializer_value_type_int16_array:
|
case sf_serializer_value_type_int16_array:
|
||||||
case sf_serializer_value_type_int32_array:
|
case sf_serializer_value_type_int32_array:
|
||||||
case sf_serializer_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_integer_array(it, remain_len -
|
||||||
SFSerializerPackFieldArray))) != 0)
|
sizeof(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_serializer_value_type_string_array:
|
||||||
|
if ((it->error_no=unpack_string_array(it, remain_len - sizeof(
|
||||||
|
SFSerializerPackFieldArray))) != 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
it->field.value.str_array = it->str_array;
|
||||||
|
break;
|
||||||
case sf_serializer_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(
|
||||||
SFSerializerPackFieldArray))) != 0)
|
SFSerializerPackFieldArray))) != 0)
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
#include "fastcommon/fast_buffer.h"
|
#include "fastcommon/fast_buffer.h"
|
||||||
#include "fastcommon/hash.h"
|
#include "fastcommon/hash.h"
|
||||||
|
|
||||||
#define SF_SERIALIZER_VALUE_TYPE_COUNT 10
|
#define SF_SERIALIZER_VALUE_TYPE_COUNT 11
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
sf_serializer_value_type_int8 = 0,
|
sf_serializer_value_type_int8 = 0,
|
||||||
|
|
@ -34,6 +34,7 @@ typedef enum {
|
||||||
sf_serializer_value_type_int16_array,
|
sf_serializer_value_type_int16_array,
|
||||||
sf_serializer_value_type_int32_array,
|
sf_serializer_value_type_int32_array,
|
||||||
sf_serializer_value_type_int64_array,
|
sf_serializer_value_type_int64_array,
|
||||||
|
sf_serializer_value_type_string_array,
|
||||||
sf_serializer_value_type_map
|
sf_serializer_value_type_map
|
||||||
} SFSerializerValueType;
|
} SFSerializerValueType;
|
||||||
|
|
||||||
|
|
@ -93,6 +94,7 @@ typedef struct sf_serializer_field_value {
|
||||||
string_t s;
|
string_t s;
|
||||||
int64_array_t int_array;
|
int64_array_t int_array;
|
||||||
key_value_array_t kv_array;
|
key_value_array_t kv_array;
|
||||||
|
string_array_t str_array;
|
||||||
} value;
|
} value;
|
||||||
} SFSerializerFieldValue;
|
} SFSerializerFieldValue;
|
||||||
|
|
||||||
|
|
@ -101,8 +103,10 @@ typedef struct sf_serializer_iterator {
|
||||||
const char *end;
|
const char *end;
|
||||||
int64_array_t int_array; //int64_t array holder
|
int64_array_t int_array; //int64_t array holder
|
||||||
key_value_array_t kv_array; //key-value array holder
|
key_value_array_t kv_array; //key-value array holder
|
||||||
|
string_array_t str_array; //string_t array holder
|
||||||
int int_array_alloc;
|
int int_array_alloc;
|
||||||
int kv_array_alloc;
|
int kv_array_alloc;
|
||||||
|
int str_array_alloc;
|
||||||
SFSerializerFieldValue field;
|
SFSerializerFieldValue field;
|
||||||
int error_no;
|
int error_no;
|
||||||
char error_info[256];
|
char error_info[256];
|
||||||
|
|
@ -352,6 +356,39 @@ static inline int sf_serializer_pack_int64_array(FastBuffer *buffer,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int sf_serializer_pack_string_array(FastBuffer *buffer,
|
||||||
|
const unsigned char fid, const string_t *strings, const int count)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int length;
|
||||||
|
SFSerializerPackFieldArray *obj;
|
||||||
|
const string_t *str;
|
||||||
|
const string_t *end;
|
||||||
|
SFSerializerPackStringValue *ps;
|
||||||
|
|
||||||
|
length = sizeof(SFSerializerPackFieldArray);
|
||||||
|
end = strings + count;
|
||||||
|
for (str=strings; str<end; str++) {
|
||||||
|
length += sizeof(SFSerializerPackStringValue) + str->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_string_array;
|
||||||
|
int2buff(count, obj->value.count);
|
||||||
|
|
||||||
|
ps = (SFSerializerPackStringValue *)obj->value.ptr;
|
||||||
|
for (str=strings; str<end; str++) {
|
||||||
|
SF_SERIALIZER_PACK_STRING_AND_MOVE_PTR(ps, str);
|
||||||
|
}
|
||||||
|
buffer->length += length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int sf_serializer_pack_map(FastBuffer *buffer,
|
static inline int sf_serializer_pack_map(FastBuffer *buffer,
|
||||||
const unsigned char fid, const key_value_pair_t *kv_pairs,
|
const unsigned char fid, const key_value_pair_t *kv_pairs,
|
||||||
const int count)
|
const int count)
|
||||||
|
|
@ -377,7 +414,7 @@ static inline int sf_serializer_pack_map(FastBuffer *buffer,
|
||||||
obj = (SFSerializerPackFieldArray *)(buffer->data + buffer->length);
|
obj = (SFSerializerPackFieldArray *)(buffer->data + buffer->length);
|
||||||
obj->field.id = fid;
|
obj->field.id = fid;
|
||||||
obj->field.type = sf_serializer_value_type_map;
|
obj->field.type = sf_serializer_value_type_map;
|
||||||
long2buff(count, obj->value.count);
|
int2buff(count, obj->value.count);
|
||||||
|
|
||||||
ps = (SFSerializerPackStringValue *)obj->value.ptr;
|
ps = (SFSerializerPackStringValue *)obj->value.ptr;
|
||||||
for (pair=kv_pairs; pair<end; pair++) {
|
for (pair=kv_pairs; pair<end; pair++) {
|
||||||
|
|
@ -417,6 +454,11 @@ static inline void sf_serializer_iterator_destroy(SFSerializerIterator *it)
|
||||||
free(it->kv_array.kv_pairs);
|
free(it->kv_array.kv_pairs);
|
||||||
it->kv_array_alloc = 0;
|
it->kv_array_alloc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (it->str_array.strings != NULL) {
|
||||||
|
free(it->str_array.strings);
|
||||||
|
it->str_array_alloc = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_serializer_unpack(SFSerializerIterator *it, const string_t *content);
|
int sf_serializer_unpack(SFSerializerIterator *it, const string_t *content);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue