* Add length param for seralization write_string
to increase a little bit the performance for big strings. * Change the format of storing strings for serial-bin.
This commit is contained in:
1 parent
89b6e1aac0
commit
cb4b43e2e8
6 files changed
+108
-24
No files matched your search
@@ -5869,7 +5869,7 @@ the following fields with the following definition:
|
|||||||
Write the float 'data' of 'size_of_type' bytes into the serial stream 'serial'.
|
Write the float 'data' of 'size_of_type' bytes into the serial stream 'serial'.
|
||||||
Return M\_SERIAL\_OK\_DONE if it succeeds, M\_SERIAL\_FAIL otherwise */
|
Return M\_SERIAL\_OK\_DONE if it succeeds, M\_SERIAL\_FAIL otherwise */
|
||||||
* write\_string:
|
* write\_string:
|
||||||
Write the null-terminated string 'data'into the serial stream 'serial'.
|
Write the null-terminated string 'data' of 'length' characters into the serial stream 'serial'.
|
||||||
Return M\_SERIAL\_OK\_DONE if it succeeds, M\_SERIAL\_FAIL otherwise */
|
Return M\_SERIAL\_OK\_DONE if it succeeds, M\_SERIAL\_FAIL otherwise */
|
||||||
* write\_array\_start:
|
* write\_array\_start:
|
||||||
Start writing an array of 'number_of_elements' objects into the serial stream 'serial'.
|
Start writing an array of 'number_of_elements' objects into the serial stream 'serial'.
|
||||||
@@ -5981,7 +5981,7 @@ The full C definition are:
|
|||||||
m_serial_return_code_t (*write_boolean)(m_serial_write_t serial, const bool b);
|
m_serial_return_code_t (*write_boolean)(m_serial_write_t serial, const bool b);
|
||||||
m_serial_return_code_t (*write_integer)(m_serial_write_t serial, const long long i, const size_t size_of_type);
|
m_serial_return_code_t (*write_integer)(m_serial_write_t serial, const long long i, const size_t size_of_type);
|
||||||
m_serial_return_code_t (*write_float)(m_serial_write_t serial, const long double f, const size_t size_of_type);
|
m_serial_return_code_t (*write_float)(m_serial_write_t serial, const long double f, const size_t size_of_type);
|
||||||
m_serial_return_code_t (*write_string)(m_serial_write_t serial, const char s[]);
|
m_serial_return_code_t (*write_string)(m_serial_write_t serial, const char s[], size_t length);
|
||||||
m_serial_return_code_t (*write_array_start)(m_serial_local_t local, m_serial_write_t serial, const size_t number_of_elements);
|
m_serial_return_code_t (*write_array_start)(m_serial_local_t local, m_serial_write_t serial, const size_t number_of_elements);
|
||||||
m_serial_return_code_t (*write_array_next)(m_serial_local_t local, m_serial_write_t serial);
|
m_serial_return_code_t (*write_array_next)(m_serial_local_t local, m_serial_write_t serial);
|
||||||
m_serial_return_code_t (*write_array_end)(m_serial_local_t local, m_serial_write_t serial);
|
m_serial_return_code_t (*write_array_end)(m_serial_local_t local, m_serial_write_t serial);
|
||||||
|
|||||||
+1
-1
@@ -50,4 +50,4 @@ V0.4.*: * The order of a list initialized using M_LET is reversed
|
|||||||
to match what is done for ARRAY (and the C++ forward_list).
|
to match what is done for ARRAY (and the C++ forward_list).
|
||||||
* Rename M_SKIP, M_KEEP & M_MID into M_SKIP_ARGS, M_KEEP_ARGS & M_MID_ARGS
|
* Rename M_SKIP, M_KEEP & M_MID into M_SKIP_ARGS, M_KEEP_ARGS & M_MID_ARGS
|
||||||
due to conflict with glibc malloc.h (that defines M_KEEP for compatibility).
|
due to conflict with glibc malloc.h (that defines M_KEEP for compatibility).
|
||||||
|
* Method write_string of m_serial expects a new argument (number of characters)
|
||||||
@@ -2995,7 +2995,7 @@ typedef struct m_serial_write_interface_s {
|
|||||||
m_serial_return_code_t (*write_boolean)(m_serial_write_t,const bool data);
|
m_serial_return_code_t (*write_boolean)(m_serial_write_t,const bool data);
|
||||||
m_serial_return_code_t (*write_integer)(m_serial_write_t,const long long data, const size_t size_of_type);
|
m_serial_return_code_t (*write_integer)(m_serial_write_t,const long long data, const size_t size_of_type);
|
||||||
m_serial_return_code_t (*write_float)(m_serial_write_t, const long double data, const size_t size_of_type);
|
m_serial_return_code_t (*write_float)(m_serial_write_t, const long double data, const size_t size_of_type);
|
||||||
m_serial_return_code_t (*write_string)(m_serial_write_t,const char data[]);
|
m_serial_return_code_t (*write_string)(m_serial_write_t,const char data[], size_t len);
|
||||||
m_serial_return_code_t (*write_array_start)(m_serial_local_t, m_serial_write_t, const size_t number_of_elements);
|
m_serial_return_code_t (*write_array_start)(m_serial_local_t, m_serial_write_t, const size_t number_of_elements);
|
||||||
m_serial_return_code_t (*write_array_next)(m_serial_local_t, m_serial_write_t);
|
m_serial_return_code_t (*write_array_next)(m_serial_local_t, m_serial_write_t);
|
||||||
m_serial_return_code_t (*write_array_end)(m_serial_local_t, m_serial_write_t);
|
m_serial_return_code_t (*write_array_end)(m_serial_local_t, m_serial_write_t);
|
||||||
@@ -3031,8 +3031,8 @@ typedef struct m_serial_write_interface_s {
|
|||||||
float: (serial)->m_interface->write_float(serial, M_AS_TYPE(float,(x)), sizeof (x)), \
|
float: (serial)->m_interface->write_float(serial, M_AS_TYPE(float,(x)), sizeof (x)), \
|
||||||
double: (serial)->m_interface->write_float(serial, M_AS_TYPE(double,(x)), sizeof (x)), \
|
double: (serial)->m_interface->write_float(serial, M_AS_TYPE(double,(x)), sizeof (x)), \
|
||||||
long double: (serial)->m_interface->write_float(serial, M_AS_TYPE(long double,(x)), sizeof (x)), \
|
long double: (serial)->m_interface->write_float(serial, M_AS_TYPE(long double,(x)), sizeof (x)), \
|
||||||
const char *: (serial)->m_interface->write_string(serial, M_AS_TYPE(const char *,(x))), \
|
const char *: (serial)->m_interface->write_string(serial, M_AS_TYPE(const char *,(x)), m_core_out_serial_strlen(M_AS_TYPE(const char *,(x))) ), \
|
||||||
char *: (serial)->m_interface->write_string(serial, M_AS_TYPE(char *,(x))), \
|
char *: (serial)->m_interface->write_string(serial, M_AS_TYPE(char *,(x)), m_core_out_serial_strlen(M_AS_TYPE(const char *,(x))) ), \
|
||||||
const void *: M_SERIAL_FAIL /* unsupported */, \
|
const void *: M_SERIAL_FAIL /* unsupported */, \
|
||||||
void *: M_SERIAL_FAIL /* unsupported */)
|
void *: M_SERIAL_FAIL /* unsupported */)
|
||||||
|
|
||||||
@@ -3089,4 +3089,15 @@ M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_float, float, read_float, long dou
|
|||||||
M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_double, double, read_float, long double)
|
M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_double, double, read_float, long double)
|
||||||
M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_ldouble, long double, read_float, long double)
|
M_IN_SERIAL_DEFAULT_TYPE_DEF(m_core_in_serial_ldouble, long double, read_float, long double)
|
||||||
|
|
||||||
|
/* Encapsulation of strlen to avoid warnings in M_OUT_SERIAL_DEFAULT_ARG
|
||||||
|
* because of expanded code will call strlen with NULL (which is illegal)
|
||||||
|
* However, the branch where it is called is unreachable, so the warning
|
||||||
|
* is not justified. */
|
||||||
|
static size_t
|
||||||
|
m_core_out_serial_strlen(const char s[])
|
||||||
|
{
|
||||||
|
assert(s != NULL);
|
||||||
|
return strlen(s);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+83
-12
@@ -30,6 +30,66 @@
|
|||||||
#include "m-core.h"
|
#include "m-core.h"
|
||||||
#include "m-string.h"
|
#include "m-string.h"
|
||||||
|
|
||||||
|
/* Internal service:
|
||||||
|
* Write size_t in the stream in a compact form to reduce consumption
|
||||||
|
* (and I/O bandwidth)
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
m_serial_bin_write_size(FILE *f, const size_t size)
|
||||||
|
{
|
||||||
|
bool b;
|
||||||
|
if (M_LIKELY(size < 253))
|
||||||
|
{
|
||||||
|
b = EOF != fputc((unsigned char) size, f);
|
||||||
|
} else if (size < 1ULL << 16) {
|
||||||
|
b = EOF != fputc(253, f); // Save 16 bits encoding
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 8), f);
|
||||||
|
b &= EOF != fputc((unsigned char) size, f);
|
||||||
|
} else if (size < 1ULL<< 32) {
|
||||||
|
b = EOF != fputc(254, f); // Save 32 bits encoding
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 24), f);
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 16), f);
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 8), f);
|
||||||
|
b &= EOF != fputc((unsigned char) size, f);
|
||||||
|
} else {
|
||||||
|
b = EOF != fputc(255, f); // Save 64 bits encoding
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 56), f);
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 48), f);
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 40), f);
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 32), f);
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 24), f);
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 16), f);
|
||||||
|
b &= EOF != fputc((unsigned char) (size >> 8), f);
|
||||||
|
b &= EOF != fputc((unsigned char) size, f);
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Internal service:
|
||||||
|
* Read size_t in the stream from a compact form to reduce consumption
|
||||||
|
* (and I/O bandwidth)
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
m_serial_bin_read_size(FILE *f, size_t *size)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
c = fgetc(f);
|
||||||
|
if (M_UNLIKELY(c == EOF)) return false;
|
||||||
|
if (M_LIKELY(c < 253)) {
|
||||||
|
*size = (size_t) c;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
size_t s = 0;
|
||||||
|
int l = (c = 255) ? 8 : (c == 254) ? 4 : 2;
|
||||||
|
for(int i = 0; i < l; i++) {
|
||||||
|
c = fgetc(f);
|
||||||
|
if (M_UNLIKELY(c == EOF)) return false;
|
||||||
|
s = (s << 8) | (size_t) c;
|
||||||
|
}
|
||||||
|
*size = s;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write the boolean 'data' into the serial stream 'serial'.
|
/* Write the boolean 'data' into the serial stream 'serial'.
|
||||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||||
static inline m_serial_return_code_t
|
static inline m_serial_return_code_t
|
||||||
@@ -105,12 +165,17 @@ m_serial_bin_write_float(m_serial_write_t serial, const long double data, const
|
|||||||
/* Write the null-terminated string 'data'into the serial stream 'serial'.
|
/* Write the null-terminated string 'data'into the serial stream 'serial'.
|
||||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||||
static inline m_serial_return_code_t
|
static inline m_serial_return_code_t
|
||||||
m_serial_bin_write_string(m_serial_write_t serial, const char data[])
|
m_serial_bin_write_string(m_serial_write_t serial, const char data[], size_t length)
|
||||||
{
|
{
|
||||||
|
STRINGI_ASSUME(length == strlen(data) );
|
||||||
FILE *f = (FILE *)serial->data[0].p;
|
FILE *f = (FILE *)serial->data[0].p;
|
||||||
size_t l = strlen(data);
|
assert(f != NULL && data != NULL);
|
||||||
size_t n = fwrite (M_ASSIGN_CAST(const void*, data), 1, l+1, f);
|
// Write first the number of (non null) characters
|
||||||
return n == l+1 ? M_SERIAL_OK_DONE : M_SERIAL_FAIL;
|
if (m_serial_bin_write_size(f, length) != true) return M_SERIAL_FAIL;
|
||||||
|
// Write the characters (excluding the final null char)
|
||||||
|
// NOTE: fwrite supports length == 0.
|
||||||
|
size_t n = fwrite (M_ASSIGN_CAST(const void*, data), 1, length, f);
|
||||||
|
return (n == length) ? M_SERIAL_OK_DONE : M_SERIAL_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start writing an array of 'number_of_elements' objects into the serial stream 'serial'.
|
/* Start writing an array of 'number_of_elements' objects into the serial stream 'serial'.
|
||||||
@@ -345,14 +410,20 @@ m_serial_bin_read_float(m_serial_read_t serial, long double *r, const size_t siz
|
|||||||
static inline m_serial_return_code_t
|
static inline m_serial_return_code_t
|
||||||
m_serial_bin_read_string(m_serial_read_t serial, struct string_s *s){
|
m_serial_bin_read_string(m_serial_read_t serial, struct string_s *s){
|
||||||
FILE *f = (FILE*) serial->data[0].p;
|
FILE *f = (FILE*) serial->data[0].p;
|
||||||
string_clean(s);
|
assert(f != NULL && s != NULL);
|
||||||
int c;
|
// First read the number of non null characters
|
||||||
c = fgetc(f);
|
size_t length;
|
||||||
while (c != 0 && c != EOF) {
|
if (m_serial_bin_read_size(f, &length) != true) return M_SERIAL_FAIL;
|
||||||
string_push_back(s, c);
|
// Use of internal string interface to dimension the string
|
||||||
c = fgetc(f);
|
string_reserve(s, length + 1);
|
||||||
}
|
char *p = stringi_get_str(s);
|
||||||
return c != EOF ? M_SERIAL_OK_DONE : M_SERIAL_FAIL;
|
stringi_set_size(s, length);
|
||||||
|
// Read the characters excluding the final null one.
|
||||||
|
// NOTE: fread supports length == 0.
|
||||||
|
size_t n = fread(M_ASSIGN_CAST(void*, p), 1, length, f);
|
||||||
|
// Force the final null character
|
||||||
|
p[length] = 0;
|
||||||
|
return (n == length) ? M_SERIAL_OK_DONE : M_SERIAL_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start reading from the stream 'serial' an array.
|
/* Start reading from the stream 'serial' an array.
|
||||||
|
|||||||
+6
-4
@@ -63,14 +63,16 @@ m_serial_json_write_float(m_serial_write_t serial, const long double data, const
|
|||||||
/* Write the null-terminated string 'data'into the serial stream 'serial'.
|
/* Write the null-terminated string 'data'into the serial stream 'serial'.
|
||||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||||
static inline m_serial_return_code_t
|
static inline m_serial_return_code_t
|
||||||
m_serial_json_write_string(m_serial_write_t serial, const char data[])
|
m_serial_json_write_string(m_serial_write_t serial, const char data[], size_t length)
|
||||||
{
|
{
|
||||||
|
STRINGI_ASSUME(length == strlen(data) );
|
||||||
FILE *f = (FILE *)serial->data[0].p;
|
FILE *f = (FILE *)serial->data[0].p;
|
||||||
/* Build dummy string to reuse string_out_str */
|
assert(f != NULL && data != NULL);
|
||||||
|
/* HACK: Build dummy string to reuse string_out_str */
|
||||||
string_t v2;
|
string_t v2;
|
||||||
uintptr_t ptr = (uintptr_t) data;
|
uintptr_t ptr = (uintptr_t) data;
|
||||||
v2->u.heap.size = strlen(data);
|
v2->u.heap.size = length;
|
||||||
v2->u.heap.alloc = v2->u.heap.size + 1;
|
v2->u.heap.alloc = length + 1;
|
||||||
v2->ptr = (char*)ptr;
|
v2->ptr = (char*)ptr;
|
||||||
string_out_str(f, v2);
|
string_out_str(f, v2);
|
||||||
return M_SERIAL_OK_DONE;
|
return M_SERIAL_OK_DONE;
|
||||||
|
|||||||
+2
-2
@@ -1241,7 +1241,7 @@ static inline m_serial_return_code_t
|
|||||||
string_out_serial(m_serial_write_t serial, const string_t v)
|
string_out_serial(m_serial_write_t serial, const string_t v)
|
||||||
{
|
{
|
||||||
assert (serial != NULL && serial->m_interface != NULL);
|
assert (serial != NULL && serial->m_interface != NULL);
|
||||||
return serial->m_interface->write_string(serial, string_get_cstr(v));
|
return serial->m_interface->write_string(serial, string_get_cstr(v), string_size(v) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the formatted string from the serializer
|
/* Read the formatted string from the serializer
|
||||||
@@ -2047,7 +2047,7 @@ namespace m_string {
|
|||||||
{ \
|
{ \
|
||||||
BOUNDED_STRINGI_CONTRACT(v, max_size); \
|
BOUNDED_STRINGI_CONTRACT(v, max_size); \
|
||||||
assert (serial != NULL && serial->m_interface != NULL); \
|
assert (serial != NULL && serial->m_interface != NULL); \
|
||||||
return serial->m_interface->write_string(serial, v->s); \
|
return serial->m_interface->write_string(serial, v->s, strlen(v->s) ); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline m_serial_return_code_t \
|
static inline m_serial_return_code_t \
|
||||||
|
|||||||
Reference in new issue
Block a user