aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlns <matzeton@googlemail.com>2022-08-08 18:16:18 +0200
committerIvan Nardi <12729895+IvanNardi@users.noreply.github.com>2022-08-24 10:49:27 +0200
commit93d65ed6503b32865b5453238c159e603bb37cb8 (patch)
tree0fe290da51ebf647f429dd12972b7e45d733dbd9 /src
parenta53f4765858285f520b8a2645da80aed2b1487b1 (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.in32
-rw-r--r--src/include/ndpi_typedefs.h1
-rw-r--r--src/lib/Makefile.in2
-rw-r--r--src/lib/ndpi_serializer.c121
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) {