diff options
author | lns <matzeton@googlemail.com> | 2022-08-08 18:16:18 +0200 |
---|---|---|
committer | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2022-08-24 10:49:27 +0200 |
commit | 93d65ed6503b32865b5453238c159e603bb37cb8 (patch) | |
tree | 0fe290da51ebf647f429dd12972b7e45d733dbd9 /src | |
parent | a53f4765858285f520b8a2645da80aed2b1487b1 (diff) |
Support serialization of double-precision floating-point numbers. Fixes #1702.
Signed-off-by: lns <matzeton@googlemail.com>
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_api.h.in | 32 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 1 | ||||
-rw-r--r-- | src/lib/Makefile.in | 2 | ||||
-rw-r--r-- | src/lib/ndpi_serializer.c | 121 |
4 files changed, 151 insertions, 5 deletions
diff --git a/src/include/ndpi_api.h.in b/src/include/ndpi_api.h.in index 2e8690203..3a81cceb3 100644 --- a/src/include/ndpi_api.h.in +++ b/src/include/ndpi_api.h.in @@ -1230,6 +1230,16 @@ extern "C" { int ndpi_serialize_uint32_float(ndpi_serializer *serializer, u_int32_t key, float value, const char *format /* e.f. "%.2f" */); /** + * Serialize a 32-bit unsigned int key and a double value + * @param serializer The serializer handle + * @param key The field name or ID + * @param value The field value + * @param format The double value format + * @return 0 on success, a negative number otherwise + */ + int ndpi_serialize_uint32_double(ndpi_serializer *serializer, u_int32_t key, double value, const char *format /* e.f. "%.2f" */); + + /** * Serialize a 32-bit unsigned int key and a string value * @param serializer The serializer handle * @param key The field name or ID @@ -1396,6 +1406,17 @@ extern "C" { int ndpi_serialize_binary_float(ndpi_serializer *_serializer, const char *key, u_int16_t klen, float value, const char *format /* e.f. "%.2f" */); /** + * Serialize an unterminated string key and a double value + * @param serializer The serializer handle + * @param key The field name or ID + * @param klen The key length + * @param value The field value + * @param format The double format + * @return 0 on success, a negative number otherwise + */ + int ndpi_serialize_binary_double(ndpi_serializer *_serializer, const char *key, u_int16_t klen, double value, const char *format /* e.f. "%.2f" */); + + /** * Serialize a string key and a a float value * @param serializer The serializer handle * @param key The field name or ID @@ -1406,6 +1427,16 @@ extern "C" { int ndpi_serialize_string_float(ndpi_serializer *serializer, const char *key, float value, const char *format /* e.f. "%.2f" */); /** + * Serialize a string key and a a double value + * @param serializer The serializer handle + * @param key The field name or ID + * @param value The field value + * @param format The double format + * @return 0 on success, a negative number otherwise + */ + int ndpi_serialize_string_double(ndpi_serializer *serializer, const char *key, double value, const char *format /* e.f. "%.2f" */); + + /** * Serialize an unterminated string key and a boolean value (JSON/CSV only, not supported by TLV) * @param serializer The serializer handle * @param key The field name or ID @@ -1586,6 +1617,7 @@ extern "C" { int ndpi_deserialize_value_int32(ndpi_deserializer *deserializer, int32_t *value); int ndpi_deserialize_value_int64(ndpi_deserializer *deserializer, int64_t *value); int ndpi_deserialize_value_float(ndpi_deserializer *deserializer, float *value); + int ndpi_deserialize_value_double(ndpi_deserializer *deserializer, double *value); int ndpi_deserialize_value_string(ndpi_deserializer *deserializer, ndpi_string *value); int ndpi_deserialize_clone_item(ndpi_deserializer *deserializer, ndpi_serializer *serializer); diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 502c7fe12..377ed0e2e 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -1618,6 +1618,7 @@ typedef enum { ndpi_serialization_int32, ndpi_serialization_int64, ndpi_serialization_float, + ndpi_serialization_double, ndpi_serialization_string, ndpi_serialization_start_of_block, ndpi_serialization_end_of_block, diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in index 201c49420..b6db5330e 100644 --- a/src/lib/Makefile.in +++ b/src/lib/Makefile.in @@ -61,7 +61,7 @@ $(NDPI_LIB_STATIC): $(OBJECTS) $(RANLIB) $@ $(NDPI_LIB_SHARED): $(OBJECTS) - $(CC) -shared -fPIC $(SONAME_FLAG) -o $@ $(LDFLAGS) $(OBJECTS) $(LIBS) + $(CC) -shared -fPIC $(CFLAGS) $(SONAME_FLAG) -o $@ $(LDFLAGS) $(OBJECTS) $(LIBS) ln -fs $(NDPI_LIB_SHARED) $(NDPI_LIB_SHARED_BASE) ln -fs $(NDPI_LIB_SHARED) $(NDPI_LIB_SHARED_BASE).$(NDPI_VERSION_MAJOR) diff --git a/src/lib/ndpi_serializer.c b/src/lib/ndpi_serializer.c index 7843ace60..e51a168d0 100644 --- a/src/lib/ndpi_serializer.c +++ b/src/lib/ndpi_serializer.c @@ -492,6 +492,15 @@ static inline void ndpi_serialize_single_float(ndpi_private_serializer *serializ /* ********************************** */ +/* TODO: fix portability across platforms */ +static inline void ndpi_serialize_single_double(ndpi_private_serializer *serializer, + double s) { + memcpy(&serializer->buffer.data[serializer->status.buffer.size_used], &s, sizeof(s)); + serializer->status.buffer.size_used += sizeof(double); +} + +/* ********************************** */ + static inline void ndpi_serialize_single_string(ndpi_private_serializer *serializer, const char *s, u_int16_t slen) { u_int16_t l = htons(slen); @@ -571,6 +580,14 @@ static inline void ndpi_deserialize_single_float(ndpi_private_deserializer *dese /* ********************************** */ +/* TODO: fix portability across platforms */ +static inline void ndpi_deserialize_single_double(ndpi_private_deserializer *deserializer, + u_int32_t offset, double *s) { + *s = *(double*)&deserializer->buffer.data[offset]; +} + +/* ********************************** */ + static inline void ndpi_deserialize_single_string(ndpi_private_deserializer *deserializer, u_int32_t offset, ndpi_string *v) { v->str_len = ntohs(*((u_int16_t *) &deserializer->buffer.data[offset])); @@ -1633,6 +1650,62 @@ int ndpi_serialize_binary_float(ndpi_serializer *_serializer, /* ********************************** */ +int ndpi_serialize_binary_double(ndpi_serializer *_serializer, + const char *key, + u_int16_t klen, + double value, + const char *format /* e.f. "%.2f" */) { + ndpi_private_serializer *serializer = (ndpi_private_serializer*)_serializer; + u_int32_t buff_diff = serializer->buffer.size - serializer->status.buffer.size_used; + u_int32_t needed; + + needed = + sizeof(u_int8_t) /* type */ + + sizeof(u_int16_t) /* key len */ + + klen /* key */ + + sizeof(double); + + if(serializer->fmt == ndpi_serialization_format_json) + needed += 32 + klen; + + if(buff_diff < needed) { + if(ndpi_extend_serializer_buffer(&serializer->buffer, needed - buff_diff) < 0) + return(-1); + buff_diff = serializer->buffer.size - serializer->status.buffer.size_used; + } + + if(serializer->fmt == ndpi_serialization_format_json) { + ndpi_serialize_json_pre(_serializer); + + if (!(serializer->status.flags & NDPI_SERIALIZER_STATUS_LIST)) { + serializer->status.buffer.size_used += ndpi_json_string_escape(key, klen, + (char *) &serializer->buffer.data[serializer->status.buffer.size_used], buff_diff); + serializer->buffer.data[serializer->status.buffer.size_used] = ':'; + serializer->status.buffer.size_used++; + buff_diff = serializer->buffer.size - serializer->status.buffer.size_used; + } + + serializer->status.buffer.size_used += ndpi_snprintf((char *) &serializer->buffer.data[serializer->status.buffer.size_used], buff_diff, format, value); + + ndpi_serialize_json_post(_serializer); + } else if(serializer->fmt == ndpi_serialization_format_csv) { + if (ndpi_serializer_header_string(serializer, key, klen) < 0) return(-1); + ndpi_serialize_csv_pre(serializer); + buff_diff = serializer->buffer.size - serializer->status.buffer.size_used; + serializer->status.buffer.size_used += ndpi_snprintf((char *) &serializer->buffer.data[serializer->status.buffer.size_used], buff_diff, format, value); + } else { + serializer->buffer.data[serializer->status.buffer.size_used++] = (ndpi_serialization_string << 4) | ndpi_serialization_double; + + ndpi_serialize_single_string(serializer, key, klen); + ndpi_serialize_single_double(serializer, value); + } + + serializer->status.flags |= NDPI_SERIALIZER_STATUS_NOT_EMPTY; + return(0); +} + +/* ********************************** */ + int ndpi_serialize_string_float(ndpi_serializer *_serializer, const char *key, float value, @@ -1642,6 +1715,16 @@ int ndpi_serialize_string_float(ndpi_serializer *_serializer, /* ********************************** */ +int ndpi_serialize_string_double(ndpi_serializer *_serializer, + const char *key, + double value, + const char *format /* e.f. "%.2f" */) +{ + return(ndpi_serialize_binary_double(_serializer, key, strlen(key), value, format)); +} + +/* ********************************** */ + /* Key is a <string, len> pair, value is a raw value */ static int ndpi_serialize_binary_raw(ndpi_serializer *_serializer, const char *key, @@ -1684,7 +1767,6 @@ static int ndpi_serialize_binary_raw(ndpi_serializer *_serializer, serializer->status.buffer.size_used += ndpi_json_string_escape(value, vlen, (char *) &serializer->buffer.data[serializer->status.buffer.size_used], buff_diff); else { - //serializer->status.buffer.size_used += ndpi_snprintf((char *) &serializer->buffer.data[serializer->status.buffer.size_used], buff_diff, value, vlen); memcpy(&serializer->buffer.data[serializer->status.buffer.size_used], value, vlen); serializer->status.buffer.size_used += vlen; } @@ -1694,9 +1776,6 @@ static int ndpi_serialize_binary_raw(ndpi_serializer *_serializer, if (ndpi_serializer_header_string(serializer, key, klen) < 0) return(-1); ndpi_serialize_csv_pre(serializer); buff_diff = serializer->buffer.size - serializer->status.buffer.size_used; - - //serializer->status.buffer.size_used += ndpi_snprintf((char *) - // &serializer->buffer.data[serializer->status.buffer.size_used], buff_diff, "%s", value); memcpy(&serializer->buffer.data[serializer->status.buffer.size_used], value, vlen); serializer->status.buffer.size_used += vlen; @@ -2210,6 +2289,9 @@ static inline int ndpi_deserialize_get_single_size(ndpi_private_deserializer *de case ndpi_serialization_float: size = sizeof(float); break; + case ndpi_serialization_double: + size = sizeof(double); + break; case ndpi_serialization_string: case ndpi_serialization_start_of_block: case ndpi_serialization_start_of_list: @@ -2528,6 +2610,37 @@ int ndpi_deserialize_value_float(ndpi_deserializer *_deserializer, /* ********************************** */ +int ndpi_deserialize_value_double(ndpi_deserializer *_deserializer, + double *value) { + ndpi_private_deserializer *deserializer = (ndpi_private_deserializer*)_deserializer; + ndpi_serialization_type kt, et; + u_int32_t buff_diff = deserializer->buffer.size - deserializer->status.buffer.size_used; + u_int16_t expected; + int size; + + expected = sizeof(u_int8_t) /* type */; + if(buff_diff < expected) return(-2); + + kt = ndpi_deserialize_get_key_subtype(deserializer); + size = ndpi_deserialize_get_single_size(deserializer, kt, deserializer->status.buffer.size_used + expected); + if(size < 0) return(-2); + + expected += size; + + et = ndpi_deserialize_get_value_subtype(deserializer); + size = ndpi_deserialize_get_single_size(deserializer, et, deserializer->status.buffer.size_used + expected); + if(size < 0) return(-2); + + if(et != ndpi_serialization_double) + return(-1); + + ndpi_deserialize_single_double(deserializer, deserializer->status.buffer.size_used + expected, value); + + return(0); +} + +/* ********************************** */ + /* Return the string value for the current element */ int ndpi_deserialize_value_string(ndpi_deserializer *_deserializer, ndpi_string *value) { |