diff options
author | Alfredo Cardigliano <cardigliano@ntop.org> | 2019-08-26 12:55:23 +0200 |
---|---|---|
committer | Alfredo Cardigliano <cardigliano@ntop.org> | 2019-08-26 12:55:23 +0200 |
commit | d043cd2ac75f88ad22ae3370d227b489c684d9b2 (patch) | |
tree | b7249e9554c93bba206feef126b85cd5ecd56684 /src | |
parent | dbf8c24ecb8fb2d5de4fc657a61aba896cb37b0a (diff) |
Serialization/deserialization of int32/int64/float with uint key
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_api.h | 13 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 3 | ||||
-rw-r--r-- | src/lib/ndpi_serializer.c | 245 |
3 files changed, 254 insertions, 7 deletions
diff --git a/src/include/ndpi_api.h b/src/include/ndpi_api.h index 94e835557..9350cd543 100644 --- a/src/include/ndpi_api.h +++ b/src/include/ndpi_api.h @@ -830,6 +830,13 @@ extern "C" { u_int32_t key, u_int32_t value); int ndpi_serialize_uint32_uint64(ndpi_serializer *serializer, u_int32_t key, u_int64_t value); + int ndpi_serialize_uint32_int32(ndpi_serializer *serializer, + u_int32_t key, int32_t value); + int ndpi_serialize_uint32_int64(ndpi_serializer *serializer, + u_int32_t key, int64_t value); + int ndpi_serialize_uint32_float(ndpi_serializer *serializer, + u_int32_t key, float value, + const char *format /* e.f. "%.2f" */); int ndpi_serialize_uint32_string(ndpi_serializer *serializer, u_int32_t key, const char *value); int ndpi_serialize_string_uint32(ndpi_serializer *serializer, @@ -862,6 +869,12 @@ extern "C" { u_int32_t *key, u_int32_t *value); int ndpi_deserialize_uint32_uint64(ndpi_deserializer *deserializer, u_int32_t *key, u_int64_t *value); + int ndpi_deserialize_uint32_int32(ndpi_deserializer *deserializer, + u_int32_t *key, int32_t *value); + int ndpi_deserialize_uint32_int64(ndpi_deserializer *deserializer, + u_int32_t *key, int64_t *value); + int ndpi_deserialize_uint32_float(ndpi_deserializer *deserializer, + u_int32_t *key, float *value); int ndpi_deserialize_uint32_string(ndpi_deserializer *deserializer, u_int32_t *key, ndpi_string *value); int ndpi_deserialize_string_int32(ndpi_deserializer *deserializer, diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 019d50155..bdb5a76e1 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1335,6 +1335,9 @@ typedef enum { ndpi_serialization_string_uint64, ndpi_serialization_string_float, ndpi_serialization_string_string, + ndpi_serialization_uint32_int32, + ndpi_serialization_uint32_int64, + ndpi_serialization_uint32_float, } ndpi_serialization_element_type; #define NDPI_SERIALIZER_STATUS_COMMA (1 << 0) diff --git a/src/lib/ndpi_serializer.c b/src/lib/ndpi_serializer.c index efaa520c2..2d98022f0 100644 --- a/src/lib/ndpi_serializer.c +++ b/src/lib/ndpi_serializer.c @@ -60,6 +60,15 @@ static u_int64_t ndpi_ntohll(u_int64_t v) { /* ********************************** */ +static int ndpi_is_number(const char *str, u_int32_t str_len) { + int i; + for (i = 0; i < str_len; i++) + if (!isdigit(str[i])) return 0; + return 1; +} + +/* ********************************** */ + /* * Escapes a string to be suitable for a JSON value, adding double quotes, and terminating the string with a null byte. * It is recommended to provide a destination buffer (dst) which is as large as double the source buffer (src) at least. @@ -489,6 +498,126 @@ int ndpi_serialize_uint32_uint64(ndpi_serializer *_serializer, /* ********************************** */ +int ndpi_serialize_uint32_int32(ndpi_serializer *_serializer, + u_int32_t key, int32_t value) { + ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; + u_int32_t buff_diff = serializer->buffer_size - serializer->size_used; + u_int16_t needed = + sizeof(u_int8_t) /* type */ + + sizeof(u_int32_t) /* key */ + + sizeof(int32_t); + + if(serializer->fmt == ndpi_serialization_format_json) + needed += 24; + + if(buff_diff < needed) { + if(ndpi_extend_serializer_buffer(_serializer, needed - buff_diff) < 0) + return(-1); + buff_diff = serializer->buffer_size - serializer->size_used; + } + + if(serializer->fmt == ndpi_serialization_format_json) { + ndpi_serialize_json_pre(_serializer); + serializer->size_used += snprintf((char *) &serializer->buffer[serializer->size_used], buff_diff, + "\"%u\":%d", key, value); + ndpi_serialize_json_post(_serializer); + } else if(serializer->fmt == ndpi_serialization_format_csv) { + serializer->size_used += snprintf((char *) &serializer->buffer[serializer->size_used], buff_diff, + "%s%d", (serializer->size_used > 0) ? serializer->csv_separator : "", value); + } else { + serializer->buffer[serializer->size_used++] = ndpi_serialization_uint32_int32; + + ndpi_serialize_single_uint32(_serializer, key); + ndpi_serialize_single_uint32(_serializer, value); + } + + return(0); +} + +/* ********************************** */ + +int ndpi_serialize_uint32_int64(ndpi_serializer *_serializer, + u_int32_t key, int64_t value) { + ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; + u_int32_t buff_diff = serializer->buffer_size - serializer->size_used; + u_int16_t needed = + sizeof(u_int8_t) /* type */ + + sizeof(u_int32_t) /* key */ + + sizeof(int64_t); + + if(serializer->fmt == ndpi_serialization_format_json) + needed += 32; + + if(buff_diff < needed) { + if(ndpi_extend_serializer_buffer(_serializer, needed - buff_diff) < 0) + return(-1); + buff_diff = serializer->buffer_size - serializer->size_used; + } + + if(serializer->fmt == ndpi_serialization_format_json) { + ndpi_serialize_json_pre(_serializer); + serializer->size_used += snprintf((char *) &serializer->buffer[serializer->size_used], buff_diff, + "\"%u\":%lld", key, (long long int)value); + ndpi_serialize_json_post(_serializer); + } else if(serializer->fmt == ndpi_serialization_format_csv) { + serializer->size_used += snprintf((char *) &serializer->buffer[serializer->size_used], buff_diff, + "%s%lld", + (serializer->size_used > 0) ? serializer->csv_separator : "", + (long long int)value); + + } else { + serializer->buffer[serializer->size_used++] = ndpi_serialization_uint32_int64; + + ndpi_serialize_single_uint32(_serializer, key); + ndpi_serialize_single_uint64(_serializer, value); + } + + return(0); +} + +/* ********************************** */ + +int ndpi_serialize_uint32_float(ndpi_serializer *_serializer, + u_int32_t key, float value, + const char *format /* e.f. "%.2f" */) { + ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; + u_int32_t buff_diff = serializer->buffer_size - serializer->size_used; + u_int16_t needed = + sizeof(u_int8_t) /* type */ + + sizeof(u_int32_t) /* key */ + + sizeof(float); + + if(serializer->fmt == ndpi_serialization_format_json) + needed += 32; + + if(buff_diff < needed) { + if(ndpi_extend_serializer_buffer(_serializer, needed - buff_diff) < 0) + return(-1); + buff_diff = serializer->buffer_size - serializer->size_used; + } + + if(serializer->fmt == ndpi_serialization_format_json) { + ndpi_serialize_json_pre(_serializer); + serializer->size_used += snprintf((char *) &serializer->buffer[serializer->size_used], buff_diff, "\"%u\":", key); + serializer->size_used += snprintf((char *) &serializer->buffer[serializer->size_used], buff_diff, format, value); + ndpi_serialize_json_post(_serializer); + } else if(serializer->fmt == ndpi_serialization_format_csv) { + serializer->size_used += snprintf((char *) &serializer->buffer[serializer->size_used], buff_diff, "%s", + (serializer->size_used > 0) ? serializer->csv_separator : ""); + serializer->size_used += snprintf((char *) &serializer->buffer[serializer->size_used], buff_diff, format, value); + + } else { + serializer->buffer[serializer->size_used++] = ndpi_serialization_uint32_float; + + ndpi_serialize_single_uint32(_serializer, key); + ndpi_serialize_single_float(_serializer, value); + } + + return(0); +} + +/* ********************************** */ + int ndpi_serialize_uint32_string(ndpi_serializer *_serializer, u_int32_t key, const char *_value) { ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; @@ -539,7 +668,12 @@ int ndpi_serialize_string_int32(ndpi_serializer *_serializer, ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; u_int16_t klen = strlen(key); u_int32_t buff_diff = serializer->buffer_size - serializer->size_used; - u_int32_t needed = + u_int32_t needed; + + if (ndpi_is_number(key, klen)) + return ndpi_serialize_uint32_int32(_serializer, atoi(key), value); + + needed = sizeof(u_int8_t) /* type */ + sizeof(u_int16_t) /* key len */ + klen /* key */ + @@ -582,7 +716,12 @@ int ndpi_serialize_string_int64(ndpi_serializer *_serializer, ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; u_int16_t klen = strlen(key); u_int32_t buff_diff = serializer->buffer_size - serializer->size_used; - u_int32_t needed = + u_int32_t needed; + + if (ndpi_is_number(key, klen)) + return ndpi_serialize_uint32_int64(_serializer, atoi(key), value); + + needed = sizeof(u_int8_t) /* type */ + sizeof(u_int16_t) /* key len */ + klen /* key */ + @@ -626,7 +765,12 @@ int ndpi_serialize_string_uint32(ndpi_serializer *_serializer, ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; u_int16_t klen = strlen(key); u_int32_t buff_diff = serializer->buffer_size - serializer->size_used; - u_int32_t needed = + u_int32_t needed; + + if (ndpi_is_number(key, klen)) + return ndpi_serialize_uint32_uint32(_serializer, atoi(key), value); + + needed = sizeof(u_int8_t) /* type */ + sizeof(u_int16_t) /* key len */ + klen /* key */ + @@ -687,7 +831,12 @@ int ndpi_serialize_string_uint64(ndpi_serializer *_serializer, ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; u_int16_t klen = strlen(key); u_int32_t buff_diff = serializer->buffer_size - serializer->size_used; - u_int32_t needed = + u_int32_t needed; + + if (ndpi_is_number(key, klen)) + return ndpi_serialize_uint32_uint64(_serializer, atoi(key), value); + + needed = sizeof(u_int8_t) /* type */ + sizeof(u_int16_t) /* key len */ + klen /* key */ + @@ -732,7 +881,12 @@ int ndpi_serialize_string_float(ndpi_serializer *_serializer, ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; u_int16_t klen = strlen(key); u_int32_t buff_diff = serializer->buffer_size - serializer->size_used; - u_int32_t needed = + u_int32_t needed; + + if (ndpi_is_number(key, klen)) + return ndpi_serialize_uint32_float(_serializer, atoi(key), value, format); + + needed = sizeof(u_int8_t) /* type */ + sizeof(u_int16_t) /* key len */ + klen /* key */ + @@ -781,13 +935,18 @@ int ndpi_serialize_string_string(ndpi_serializer *_serializer, ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; const char *value = _value ? _value : ""; u_int16_t klen = strlen(key), vlen = strlen(value); - u_int32_t needed = + u_int32_t buff_diff = serializer->buffer_size - serializer->size_used; + u_int32_t needed; + + if (ndpi_is_number(key, klen)) + return ndpi_serialize_uint32_string(_serializer, atoi(key), _value); + + needed = sizeof(u_int8_t) /* type */ + sizeof(u_int16_t) /* key len */ + klen + sizeof(u_int16_t) /* len */ + vlen; - u_int32_t buff_diff = serializer->buffer_size - serializer->size_used; if(serializer->fmt == ndpi_serialization_format_json) needed += 16 + klen + vlen; @@ -940,6 +1099,78 @@ int ndpi_deserialize_uint32_uint64(ndpi_deserializer *_deserializer, /* ********************************** */ +int ndpi_deserialize_uint32_int32(ndpi_deserializer *_deserializer, + u_int32_t *key, int32_t *value) { + ndpi_private_deserializer *deserializer = (ndpi_private_deserializer*)_deserializer; + + if(ndpi_deserialize_get_nextitem_type(_deserializer) == ndpi_serialization_uint32_int32) { + u_int32_t buff_diff = deserializer->buffer_size - deserializer->size_used; + u_int16_t expected = + sizeof(u_int8_t) /* type */ + + sizeof(u_int32_t) /* key */ + + sizeof(int32_t); + + if(buff_diff < expected) return(-2); + + deserializer->size_used++; /* Skip element type */ + ndpi_deserialize_single_uint32(_deserializer, key); + ndpi_deserialize_single_int32(_deserializer, value); + + return(0); + } else + return(-1); +} + +/* ********************************** */ + +int ndpi_deserialize_uint32_int64(ndpi_deserializer *_deserializer, + u_int32_t *key, int64_t *value) { + ndpi_private_deserializer *deserializer = (ndpi_private_deserializer*)_deserializer; + + if(ndpi_deserialize_get_nextitem_type(_deserializer) == ndpi_serialization_uint32_int64) { + u_int32_t buff_diff = deserializer->buffer_size - deserializer->size_used; + u_int16_t expected = + sizeof(u_int8_t) /* type */ + + sizeof(u_int32_t) /* key */ + + sizeof(int64_t); + + if(buff_diff < expected) return(-2); + + deserializer->size_used++; /* Skip element type */ + ndpi_deserialize_single_uint32(_deserializer, key); + ndpi_deserialize_single_int64(_deserializer, value); + + return(0); + } else + return(-1); +} + +/* ********************************** */ + +int ndpi_deserialize_uint32_float(ndpi_deserializer *_deserializer, + u_int32_t *key, float *value) { + ndpi_private_deserializer *deserializer = (ndpi_private_deserializer*)_deserializer; + + if(ndpi_deserialize_get_nextitem_type(_deserializer) == ndpi_serialization_uint32_float) { + u_int32_t buff_diff = deserializer->buffer_size - deserializer->size_used; + u_int16_t expected = + sizeof(u_int8_t) /* type */ + + sizeof(u_int32_t) /* key */ + + sizeof(float); + + if(buff_diff < expected) return(-2); + + deserializer->size_used++; /* Skip element type */ + ndpi_deserialize_single_uint32(_deserializer, key); + ndpi_deserialize_single_float(_deserializer, value); + + return(0); + } else + return(-1); +} + +/* ********************************** */ + int ndpi_deserialize_uint32_string(ndpi_deserializer *_deserializer, u_int32_t *key, ndpi_string *value) { ndpi_private_deserializer *deserializer = (ndpi_private_deserializer*)_deserializer; |