* 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'.
|
||||
Return M\_SERIAL\_OK\_DONE if it succeeds, M\_SERIAL\_FAIL otherwise */
|
||||
* 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 */
|
||||
* write\_array\_start:
|
||||
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_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_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_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);
|
||||
|
||||
+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).
|
||||
* 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).
|
||||
|
||||
* 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_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_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_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);
|
||||
@@ -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)), \
|
||||
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)), \
|
||||
const char *: (serial)->m_interface->write_string(serial, M_AS_TYPE(const char *,(x))), \
|
||||
char *: (serial)->m_interface->write_string(serial, M_AS_TYPE(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)), m_core_out_serial_strlen(M_AS_TYPE(const char *,(x))) ), \
|
||||
const 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_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
|
||||
+83
-12
@@ -30,6 +30,66 @@
|
||||
#include "m-core.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'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
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'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
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;
|
||||
size_t l = strlen(data);
|
||||
size_t n = fwrite (M_ASSIGN_CAST(const void*, data), 1, l+1, f);
|
||||
return n == l+1 ? M_SERIAL_OK_DONE : M_SERIAL_FAIL;
|
||||
assert(f != NULL && data != NULL);
|
||||
// Write first the number of (non null) characters
|
||||
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'.
|
||||
@@ -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
|
||||
m_serial_bin_read_string(m_serial_read_t serial, struct string_s *s){
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
string_clean(s);
|
||||
int c;
|
||||
c = fgetc(f);
|
||||
while (c != 0 && c != EOF) {
|
||||
string_push_back(s, c);
|
||||
c = fgetc(f);
|
||||
}
|
||||
return c != EOF ? M_SERIAL_OK_DONE : M_SERIAL_FAIL;
|
||||
assert(f != NULL && s != NULL);
|
||||
// First read the number of non null characters
|
||||
size_t length;
|
||||
if (m_serial_bin_read_size(f, &length) != true) return M_SERIAL_FAIL;
|
||||
// Use of internal string interface to dimension the string
|
||||
string_reserve(s, length + 1);
|
||||
char *p = stringi_get_str(s);
|
||||
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.
|
||||
|
||||
+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'.
|
||||
Return M_SERIAL_OK_DONE if it succeeds, M_SERIAL_FAIL otherwise */
|
||||
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;
|
||||
/* 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;
|
||||
uintptr_t ptr = (uintptr_t) data;
|
||||
v2->u.heap.size = strlen(data);
|
||||
v2->u.heap.alloc = v2->u.heap.size + 1;
|
||||
v2->u.heap.size = length;
|
||||
v2->u.heap.alloc = length + 1;
|
||||
v2->ptr = (char*)ptr;
|
||||
string_out_str(f, v2);
|
||||
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)
|
||||
{
|
||||
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
|
||||
@@ -2047,7 +2047,7 @@ namespace m_string {
|
||||
{ \
|
||||
BOUNDED_STRINGI_CONTRACT(v, max_size); \
|
||||
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 \
|
||||
|
||||
Reference in new issue
Block a user