Add local argument to serial interface to enable serial interface to create local parameters if needed (for example for serial binary)
This commit is contained in:
1 parent
b6d5b5462b
commit
05a68157bc
10 files changed
+147
-106
No files matched your search
@@ -913,14 +913,15 @@
|
||||
ARRAYI_CONTRACT(array); \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_return_code_t ret; \
|
||||
ret = f->interface->write_array_start(f, array->size); \
|
||||
m_serial_local_t local; \
|
||||
ret = f->interface->write_array_start(local, f, array->size); \
|
||||
for (size_t i = 0; i < array->size; i++) { \
|
||||
type const *item = M_C(name, _cget)(array, i); \
|
||||
if (i != 0) \
|
||||
ret |= f->interface->write_array_next(f); \
|
||||
ret |= f->interface->write_array_next(local, f); \
|
||||
ret |= M_CALL_OUT_SERIAL(oplist, f, *item); \
|
||||
} \
|
||||
ret |= f->interface->write_array_end(f); \
|
||||
ret |= f->interface->write_array_end(local, f); \
|
||||
return ret & M_SERIAL_FAIL; \
|
||||
} \
|
||||
, /* no OUT_SERIAL */ ) \
|
||||
@@ -932,9 +933,10 @@
|
||||
ARRAYI_CONTRACT(array); \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_return_code_t ret; \
|
||||
m_serial_local_t local; \
|
||||
size_t estimated_size = 0; \
|
||||
M_C(name,_clean)(array); \
|
||||
ret = f->interface->read_array_start(f, &estimated_size); \
|
||||
ret = f->interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
if (estimated_size != 0) M_C(name, _resize)(array, estimated_size); \
|
||||
type item; \
|
||||
@@ -943,7 +945,7 @@
|
||||
ret = M_CALL_IN_SERIAL(oplist, item, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_C(name, _push_back)(array, item); \
|
||||
} while ((ret = f->interface->read_array_next(f)) == M_SERIAL_OK_CONTINUE); \
|
||||
} while ((ret = f->interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
ARRAYI_CONTRACT(array); \
|
||||
return ret; \
|
||||
|
||||
+14
-13
@@ -1140,37 +1140,38 @@
|
||||
BPTREEI_CONTRACT(N, key_oplist, t1); \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_return_code_t ret; \
|
||||
m_serial_local_t local; \
|
||||
const M_C(name, _type_t) *item; \
|
||||
bool first_done = false; \
|
||||
it_t it; \
|
||||
/* Format is different between associative container \
|
||||
& set container */ \
|
||||
M_IF(isMap)( \
|
||||
ret = f->interface->write_map_start(f, t1->size); \
|
||||
ret = f->interface->write_map_start(local, f, t1->size); \
|
||||
for (M_C(name, _it)(it, t1) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
item = M_C(name, _cref)(it); \
|
||||
if (first_done) \
|
||||
ret |= f->interface->write_map_next(f); \
|
||||
ret |= f->interface->write_map_next(local, f); \
|
||||
ret |= M_CALL_OUT_SERIAL(key_oplist, f, *item->key_ptr); \
|
||||
ret |= f->interface->write_map_value(f); \
|
||||
ret |= f->interface->write_map_value(local, f); \
|
||||
ret |= M_CALL_OUT_SERIAL(value_oplist, f, *item->value_ptr); \
|
||||
first_done = true; \
|
||||
} \
|
||||
ret |= f->interface->write_map_end(f); \
|
||||
ret |= f->interface->write_map_end(local, f); \
|
||||
, \
|
||||
ret = f->interface->write_array_start(f, t1->size); \
|
||||
ret = f->interface->write_array_start(local, f, t1->size); \
|
||||
for (M_C(name, _it)(it, t1) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
item = M_C(name, _cref)(it); \
|
||||
if (first_done) \
|
||||
ret |= f->interface->write_array_next(f); \
|
||||
ret |= f->interface->write_array_next(local, f); \
|
||||
ret |= M_CALL_OUT_SERIAL(key_oplist, f, *item); \
|
||||
first_done = true; \
|
||||
} \
|
||||
ret |= f->interface->write_array_end(f); \
|
||||
ret |= f->interface->write_array_end(local, f); \
|
||||
) \
|
||||
return ret & M_SERIAL_FAIL; \
|
||||
} \
|
||||
@@ -1182,43 +1183,43 @@
|
||||
{ \
|
||||
BPTREEI_CONTRACT(N, key_oplist, t1); \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
size_t estimated_size = 0; \
|
||||
key_t key; \
|
||||
M_C(name,_clean)(t1); \
|
||||
M_IF(isMap)( \
|
||||
value_t value; \
|
||||
ret = f->interface->read_map_start(f, &estimated_size); \
|
||||
ret = f->interface->read_map_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
M_CALL_INIT (value_oplist, value); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(key_oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) return M_SERIAL_FAIL; \
|
||||
ret = f->interface->read_map_value(f); \
|
||||
ret = f->interface->read_map_value(local, f); \
|
||||
if (ret != M_SERIAL_OK_CONTINUE) return M_SERIAL_FAIL; \
|
||||
ret = M_CALL_IN_SERIAL(value_oplist, value, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) return M_SERIAL_FAIL; \
|
||||
M_C(name, _set_at)(t1, key, value); \
|
||||
} while ((ret = f->interface->read_map_next(f)) == M_SERIAL_OK_CONTINUE); \
|
||||
} while ((ret = f->interface->read_map_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
M_CALL_CLEAR(value_oplist, value); \
|
||||
, \
|
||||
ret = f->interface->read_array_start(f, &estimated_size); \
|
||||
ret = f->interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(key_oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_C(name, _push)(t1, key); \
|
||||
} while ((ret = f->interface->read_array_next(f)) == M_SERIAL_OK_CONTINUE); \
|
||||
} while ((ret = f->interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
) /* End of IF isMap */ \
|
||||
return ret; \
|
||||
} \
|
||||
, /* no in_serial */ ) \
|
||||
\
|
||||
\
|
||||
|
||||
|
||||
#endif
|
||||
@@ -2591,7 +2591,9 @@ typedef union m_serial_ll_u {
|
||||
void *p;
|
||||
} m_serial_ll_t;
|
||||
|
||||
// Object to handle the construction of a serial write/read of an object that needs multiple calls (array, map, ...)
|
||||
/* Object to handle the construction of a serial write/read of an object
|
||||
that needs multiple calls (array, map, ...)
|
||||
It is common to all calls to the same object */
|
||||
typedef struct m_serial_local_s {
|
||||
m_serial_ll_t data[M_SERIAL_MAX_DATA_SIZE];
|
||||
} m_serial_local_t[1];
|
||||
@@ -2607,19 +2609,19 @@ struct string_s;
|
||||
|
||||
// Interface exported by the serial read object.
|
||||
typedef struct m_serial_read_interface_s {
|
||||
m_serial_return_code_t (*read_boolean)(m_serial_read_t,bool *);
|
||||
m_serial_return_code_t (*read_integer)(m_serial_read_t, long long *, const size_t size_of_type);
|
||||
m_serial_return_code_t (*read_float)(m_serial_read_t, long double *, const size_t size_of_type);
|
||||
m_serial_return_code_t (*read_string)(m_serial_read_t, struct string_s *);
|
||||
m_serial_return_code_t (*read_array_start)(m_serial_read_t, size_t *);
|
||||
m_serial_return_code_t (*read_array_next)(m_serial_read_t); // Return M_SERIAL_OK_DONE when array is finished parsing.
|
||||
m_serial_return_code_t (*read_map_start)(m_serial_read_t, size_t *);
|
||||
m_serial_return_code_t (*read_map_value)(m_serial_read_t);
|
||||
m_serial_return_code_t (*read_map_next)(m_serial_read_t); // Return M_SERIAL_OK_DONE when map is finished parsing.
|
||||
m_serial_return_code_t (*read_tuple_start)(m_serial_read_t);
|
||||
m_serial_return_code_t (*read_tuple_id)(m_serial_read_t, const char *const field_name [], const int max, int *); // Return M_SERIAL_OK_DONE when tuple is finished parsing.
|
||||
m_serial_return_code_t (*read_variant_start)(m_serial_read_t, const char *const field_name[], const int max, int*);
|
||||
m_serial_return_code_t (*read_variant_end)(m_serial_read_t);
|
||||
m_serial_return_code_t (*read_boolean)(m_serial_read_t,bool *);
|
||||
m_serial_return_code_t (*read_integer)(m_serial_read_t, long long *, const size_t size_of_type);
|
||||
m_serial_return_code_t (*read_float)(m_serial_read_t, long double *, const size_t size_of_type);
|
||||
m_serial_return_code_t (*read_string)(m_serial_read_t, struct string_s *);
|
||||
m_serial_return_code_t (*read_array_start)(m_serial_local_t, m_serial_read_t, size_t *);
|
||||
m_serial_return_code_t (*read_array_next)(m_serial_local_t, m_serial_read_t); // Return M_SERIAL_OK_DONE when array is finished parsing.
|
||||
m_serial_return_code_t (*read_map_start)(m_serial_local_t, m_serial_read_t, size_t *);
|
||||
m_serial_return_code_t (*read_map_value)(m_serial_local_t, m_serial_read_t);
|
||||
m_serial_return_code_t (*read_map_next)(m_serial_local_t, m_serial_read_t); // Return M_SERIAL_OK_DONE when map is finished parsing.
|
||||
m_serial_return_code_t (*read_tuple_start)(m_serial_local_t, m_serial_read_t);
|
||||
m_serial_return_code_t (*read_tuple_id)(m_serial_local_t, m_serial_read_t, const char *const field_name [], const int max, int *); // Return M_SERIAL_OK_DONE when tuple is finished parsing.
|
||||
m_serial_return_code_t (*read_variant_start)(m_serial_local_t, m_serial_read_t, const char *const field_name[], const int max, int*);
|
||||
m_serial_return_code_t (*read_variant_end)(m_serial_local_t, m_serial_read_t);
|
||||
} m_serial_read_interface_t;
|
||||
|
||||
|
||||
@@ -2631,22 +2633,22 @@ typedef struct m_serial_write_s {
|
||||
|
||||
// Interface exported by the serial write object.
|
||||
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_array_start)(m_serial_write_t, const size_t number_of_elements);
|
||||
m_serial_return_code_t (*write_array_next)(m_serial_write_t);
|
||||
m_serial_return_code_t (*write_array_end)(m_serial_write_t);
|
||||
m_serial_return_code_t (*write_map_start)(m_serial_write_t, const size_t number_of_elements);
|
||||
m_serial_return_code_t (*write_map_value)(m_serial_write_t);
|
||||
m_serial_return_code_t (*write_map_next)(m_serial_write_t);
|
||||
m_serial_return_code_t (*write_map_end)(m_serial_write_t);
|
||||
m_serial_return_code_t (*write_tuple_start)(m_serial_write_t);
|
||||
m_serial_return_code_t (*write_tuple_id)(m_serial_write_t, const char * const field_name[], const int max, const int index);
|
||||
m_serial_return_code_t (*write_tuple_end)(m_serial_write_t);
|
||||
m_serial_return_code_t (*write_variant_start)(m_serial_write_t, const char * const field_name[], const int max, const int index);
|
||||
m_serial_return_code_t (*write_variant_end)(m_serial_write_t);
|
||||
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_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);
|
||||
m_serial_return_code_t (*write_map_start)(m_serial_local_t, m_serial_write_t, const size_t number_of_elements);
|
||||
m_serial_return_code_t (*write_map_value)(m_serial_local_t, m_serial_write_t);
|
||||
m_serial_return_code_t (*write_map_next)(m_serial_local_t, m_serial_write_t);
|
||||
m_serial_return_code_t (*write_map_end)(m_serial_local_t, m_serial_write_t);
|
||||
m_serial_return_code_t (*write_tuple_start)(m_serial_local_t, m_serial_write_t);
|
||||
m_serial_return_code_t (*write_tuple_id)(m_serial_local_t, m_serial_write_t, const char * const field_name[], const int max, const int index);
|
||||
m_serial_return_code_t (*write_tuple_end)(m_serial_local_t, m_serial_write_t);
|
||||
m_serial_return_code_t (*write_variant_start)(m_serial_local_t, m_serial_write_t, const char * const field_name[], const int max, const int index);
|
||||
m_serial_return_code_t (*write_variant_end)(m_serial_local_t, m_serial_write_t);
|
||||
} m_serial_write_interface_t;
|
||||
|
||||
/* Convert a C default variale (bool, integer, float) to a Serialized data */
|
||||
|
||||
@@ -858,20 +858,21 @@
|
||||
{ \
|
||||
DEQUEI_CONTRACT(deque); \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
bool first_done = false; \
|
||||
ret = f->interface->write_array_start(f, deque->count); \
|
||||
ret = f->interface->write_array_start(local, f, deque->count); \
|
||||
M_C(name, _it_t) it; \
|
||||
for (M_C(name, _it)(it, deque) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
type const *item = M_C(name, _cref)(it); \
|
||||
if (first_done) \
|
||||
ret |= f->interface->write_array_next(f); \
|
||||
ret |= f->interface->write_array_next(local, f); \
|
||||
ret |= M_CALL_OUT_SERIAL(oplist, f, *item); \
|
||||
first_done = true; \
|
||||
} \
|
||||
ret |= f->interface->write_array_end(f); \
|
||||
ret |= f->interface->write_array_end(local, f); \
|
||||
return ret & M_SERIAL_FAIL; \
|
||||
} \
|
||||
, /* no OUT_SERIAL */ ) \
|
||||
@@ -882,10 +883,11 @@
|
||||
{ \
|
||||
DEQUEI_CONTRACT(deque); \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
size_t estimated_size = 0; \
|
||||
M_C(name,_clean)(deque); \
|
||||
ret = f->interface->read_array_start(f, &estimated_size); \
|
||||
ret = f->interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
@@ -893,7 +895,7 @@
|
||||
ret = M_CALL_IN_SERIAL(oplist, item, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_C(name, _push_back)(deque, item); \
|
||||
} while ((ret = f->interface->read_array_next(f)) == M_SERIAL_OK_CONTINUE); \
|
||||
} while ((ret = f->interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
return ret; \
|
||||
} \
|
||||
|
||||
@@ -786,6 +786,7 @@
|
||||
M_C(name, _out_serial)(m_serial_write_t f, dict_t const t1) \
|
||||
{ \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
const M_C(name, _type_t) *item; \
|
||||
bool first_done = false; \
|
||||
@@ -793,31 +794,31 @@
|
||||
/* Format is different between associative container \
|
||||
& set container */ \
|
||||
M_IF(isSet)( \
|
||||
ret = f->interface->write_array_start(f, M_C(name, _size)(t1)); \
|
||||
ret = f->interface->write_array_start(local, f, M_C(name, _size)(t1)); \
|
||||
for (M_C(name, _it)(it, t1) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
item = M_C(name, _cref)(it); \
|
||||
if (first_done) \
|
||||
ret |= f->interface->write_array_next(f); \
|
||||
ret |= f->interface->write_array_next(local, f); \
|
||||
ret |= M_CALL_OUT_SERIAL(key_oplist, f, *item); \
|
||||
first_done = true; \
|
||||
} \
|
||||
ret |= f->interface->write_array_end(f); \
|
||||
ret |= f->interface->write_array_end(local, f); \
|
||||
, \
|
||||
ret = f->interface->write_map_start(f, M_C(name, _size)(t1)); \
|
||||
ret = f->interface->write_map_start(local, f, M_C(name, _size)(t1)); \
|
||||
for (M_C(name, _it)(it, t1) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
item = M_C(name, _cref)(it); \
|
||||
if (first_done) \
|
||||
ret |= f->interface->write_map_next(f); \
|
||||
ret |= f->interface->write_map_next(local, f); \
|
||||
ret |= M_CALL_OUT_SERIAL(key_oplist, f, item->key); \
|
||||
ret |= f->interface->write_map_value(f); \
|
||||
ret |= f->interface->write_map_value(local, f); \
|
||||
ret |= M_CALL_OUT_SERIAL(value_oplist, f, item->value); \
|
||||
first_done = true; \
|
||||
} \
|
||||
ret |= f->interface->write_map_end(f); \
|
||||
ret |= f->interface->write_map_end(local, f); \
|
||||
) \
|
||||
return ret & M_SERIAL_FAIL; \
|
||||
} \
|
||||
@@ -828,35 +829,36 @@
|
||||
M_C(name, _in_serial)(dict_t t1, m_serial_read_t f) \
|
||||
{ \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
size_t estimated_size = 0; \
|
||||
key_type key; \
|
||||
M_C(name,_clean)(t1); \
|
||||
M_IF(isSet)( \
|
||||
ret = f->interface->read_array_start(f, &estimated_size); \
|
||||
ret = f->interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(key_oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_C(name, _push)(t1, key); \
|
||||
} while ((ret = f->interface->read_array_next(f)) == M_SERIAL_OK_CONTINUE); \
|
||||
} while ((ret = f->interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
, \
|
||||
value_type value; \
|
||||
ret = f->interface->read_map_start(f, &estimated_size); \
|
||||
ret = f->interface->read_map_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
M_CALL_INIT(key_oplist, key); \
|
||||
M_CALL_INIT (value_oplist, value); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(key_oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) return M_SERIAL_FAIL; \
|
||||
ret = f->interface->read_map_value(f); \
|
||||
ret = f->interface->read_map_value(local, f); \
|
||||
if (ret != M_SERIAL_OK_CONTINUE) return M_SERIAL_FAIL; \
|
||||
ret = M_CALL_IN_SERIAL(value_oplist, value, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) return M_SERIAL_FAIL; \
|
||||
M_C(name, _set_at)(t1, key, value); \
|
||||
} while ((ret = f->interface->read_map_next(f)) == M_SERIAL_OK_CONTINUE); \
|
||||
} while ((ret = f->interface->read_map_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(key_oplist, key); \
|
||||
M_CALL_CLEAR(value_oplist, value); \
|
||||
) /* End of IF isSet */ \
|
||||
|
||||
@@ -685,19 +685,20 @@
|
||||
assert (list != NULL); \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_return_code_t ret; \
|
||||
m_serial_local_t local; \
|
||||
bool first_done = false; \
|
||||
ret = f->interface->write_array_start(f, 0); /* TBC: 0? */ \
|
||||
ret = f->interface->write_array_start(local, f, 0); /* TBC: 0? */ \
|
||||
M_C(name, _it_t) it; \
|
||||
for (M_C(name, _it)(it, list) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
type const *item = M_C(name, _cref)(it); \
|
||||
if (first_done) \
|
||||
ret |= f->interface->write_array_next(f); \
|
||||
ret |= f->interface->write_array_next(local, f); \
|
||||
ret |= M_CALL_OUT_SERIAL(oplist, f, *item); \
|
||||
first_done = true; \
|
||||
} \
|
||||
ret |= f->interface->write_array_end(f); \
|
||||
ret |= f->interface->write_array_end(local, f); \
|
||||
return ret & M_SERIAL_FAIL; \
|
||||
} \
|
||||
, /* no OUT_SERIAL */ ) \
|
||||
@@ -709,9 +710,10 @@
|
||||
assert (list != NULL); \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_return_code_t ret; \
|
||||
m_serial_local_t local; \
|
||||
size_t estimated_size = 0; \
|
||||
M_C(name,_clean)(list); \
|
||||
ret = f->interface->read_array_start(f, &estimated_size); \
|
||||
ret = f->interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
type item; \
|
||||
M_CALL_INIT(oplist, item); \
|
||||
@@ -719,7 +721,7 @@
|
||||
ret = M_CALL_IN_SERIAL(oplist, item, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_C(name, _push_back)(list, item); \
|
||||
} while ((ret = f->interface->read_array_next(f)) == M_SERIAL_OK_CONTINUE); \
|
||||
} while ((ret = f->interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(oplist, item); \
|
||||
M_C(name, _reverse)(list); \
|
||||
return ret; \
|
||||
|
||||
+7
-5
@@ -998,21 +998,22 @@ typedef enum {
|
||||
{ \
|
||||
RBTREEI_CONTRACT(t1); \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
const M_C(name, _type_t) *item; \
|
||||
bool first_done = false; \
|
||||
tree_it_t it; \
|
||||
ret = f->interface->write_array_start(f, t1->size); \
|
||||
ret = f->interface->write_array_start(local, f, t1->size); \
|
||||
for (M_C(name, _it)(it, t1) ; \
|
||||
!M_C(name, _end_p)(it); \
|
||||
M_C(name, _next)(it)){ \
|
||||
item = M_C(name, _cref)(it); \
|
||||
if (first_done) \
|
||||
ret |= f->interface->write_array_next(f); \
|
||||
ret |= f->interface->write_array_next(local, f); \
|
||||
ret |= M_CALL_OUT_SERIAL(oplist, f, *item); \
|
||||
first_done = true; \
|
||||
} \
|
||||
ret |= f->interface->write_array_end(f); \
|
||||
ret |= f->interface->write_array_end(local, f); \
|
||||
return ret & M_SERIAL_FAIL; \
|
||||
} \
|
||||
, /* no OUT_SERIAL */ ) \
|
||||
@@ -1023,18 +1024,19 @@ typedef enum {
|
||||
{ \
|
||||
RBTREEI_CONTRACT(t1); \
|
||||
assert (f != NULL && f->interface != NULL); \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
size_t estimated_size = 0; \
|
||||
type key; \
|
||||
M_C(name,_clean)(t1); \
|
||||
ret = f->interface->read_array_start(f, &estimated_size); \
|
||||
ret = f->interface->read_array_start(local, f, &estimated_size); \
|
||||
if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \
|
||||
M_CALL_INIT(oplist, key); \
|
||||
do { \
|
||||
ret = M_CALL_IN_SERIAL(oplist, key, f); \
|
||||
if (ret != M_SERIAL_OK_DONE) { break; } \
|
||||
M_C(name, _push)(t1, key); \
|
||||
} while ((ret = f->interface->read_array_next(f)) == M_SERIAL_OK_CONTINUE); \
|
||||
} while ((ret = f->interface->read_array_next(local, f)) == M_SERIAL_OK_CONTINUE); \
|
||||
M_CALL_CLEAR(oplist, key); \
|
||||
return ret; \
|
||||
} \
|
||||
|
||||
+45
-21
@@ -78,8 +78,9 @@ m_serial_json_write_string(m_serial_write_t serial, const char data[])
|
||||
of the array is unkown.
|
||||
Return M_SERIAL_OK_CONTINUE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_array_start(m_serial_write_t serial, const size_t number_of_elements)
|
||||
m_serial_json_write_array_start(m_serial_local_t local, m_serial_write_t serial, const size_t number_of_elements)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
(void) number_of_elements; // Ignored
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, "[");
|
||||
@@ -89,8 +90,9 @@ m_serial_json_write_array_start(m_serial_write_t serial, const size_t number_of_
|
||||
/* Write an array separator between elements of an array into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_array_next(m_serial_write_t serial)
|
||||
m_serial_json_write_array_next(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, ",");
|
||||
return n > 0 ? M_SERIAL_OK_CONTINUE : M_SERIAL_FAIL;
|
||||
@@ -99,8 +101,9 @@ m_serial_json_write_array_next(m_serial_write_t serial)
|
||||
/* End the writing of an array into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_array_end(m_serial_write_t serial)
|
||||
m_serial_json_write_array_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, "]");
|
||||
return n > 0 ? M_SERIAL_OK_DONE : M_SERIAL_FAIL;
|
||||
@@ -111,8 +114,9 @@ m_serial_json_write_array_end(m_serial_write_t serial)
|
||||
is unkown.
|
||||
Return M_SERIAL_OK_CONTINUE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_map_start(m_serial_write_t serial, const size_t number_of_elements)
|
||||
m_serial_json_write_map_start(m_serial_local_t local, m_serial_write_t serial, const size_t number_of_elements)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
(void) number_of_elements; // Ignored
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, "{");
|
||||
@@ -122,8 +126,9 @@ m_serial_json_write_map_start(m_serial_write_t serial, const size_t number_of_el
|
||||
/* Write a value separator between element of the same pair of a map into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_map_value(m_serial_write_t serial)
|
||||
m_serial_json_write_map_value(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, ":");
|
||||
return n > 0 ? M_SERIAL_OK_CONTINUE : M_SERIAL_FAIL;
|
||||
@@ -132,8 +137,9 @@ m_serial_json_write_map_value(m_serial_write_t serial)
|
||||
/* Write a map separator between elements of a map into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_map_next(m_serial_write_t serial)
|
||||
m_serial_json_write_map_next(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, ",");
|
||||
return n > 0 ? M_SERIAL_OK_CONTINUE : M_SERIAL_FAIL;
|
||||
@@ -142,8 +148,9 @@ m_serial_json_write_map_next(m_serial_write_t serial)
|
||||
/* End the writing of a map into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_map_end(m_serial_write_t serial)
|
||||
m_serial_json_write_map_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, "}");
|
||||
return n > 0 ? M_SERIAL_OK_DONE : M_SERIAL_FAIL;
|
||||
@@ -152,8 +159,9 @@ m_serial_json_write_map_end(m_serial_write_t serial)
|
||||
/* Start Writing a tuple into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_tuple_start(m_serial_write_t serial)
|
||||
m_serial_json_write_tuple_start(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, "{");
|
||||
return n > 0 ? M_SERIAL_OK_CONTINUE : M_SERIAL_FAIL;
|
||||
@@ -162,8 +170,9 @@ m_serial_json_write_tuple_start(m_serial_write_t serial)
|
||||
/* Start writing the field named field_name[index] of a tuple into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_CONTINUE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_tuple_id(m_serial_write_t serial, const char *const field_name[], const int max, const int index)
|
||||
m_serial_json_write_tuple_id(m_serial_local_t local, m_serial_write_t serial, const char *const field_name[], const int max, const int index)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
(void) max; // Ignored
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, "%c\"%s\":", index == 0 ? ' ' : ',', field_name[index]);
|
||||
@@ -173,8 +182,9 @@ m_serial_json_write_tuple_id(m_serial_write_t serial, const char *const field_na
|
||||
/* End the write of a tuple into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_tuple_end(m_serial_write_t serial)
|
||||
m_serial_json_write_tuple_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, "}");
|
||||
return n > 0 ? M_SERIAL_OK_DONE : M_SERIAL_FAIL;
|
||||
@@ -186,11 +196,14 @@ m_serial_json_write_tuple_end(m_serial_write_t serial)
|
||||
Otherwise, the field 'field_name[index]' will be filled.
|
||||
Return M_SERIAL_OK_CONTINUE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_variant_start(m_serial_write_t serial, const char *const field_name[], const int max, const int index)
|
||||
m_serial_json_write_variant_start(m_serial_local_t local, m_serial_write_t serial, const char *const field_name[], const int max, const int index)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
(void) max; // argument not used
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n;
|
||||
if (index >= 0) {
|
||||
assert (index < max);
|
||||
n = fprintf(f, "{\"%s\":", field_name[index]);
|
||||
return n > 0 ? M_SERIAL_OK_CONTINUE : M_SERIAL_FAIL;
|
||||
} else {
|
||||
@@ -202,8 +215,9 @@ m_serial_json_write_variant_start(m_serial_write_t serial, const char *const fie
|
||||
/* End Writing a variant into the serial stream 'serial'.
|
||||
Return M_SERIAL_OK_DONE if the operation succeed, M_SERIAL_FAIL otherwise */
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_write_variant_end(m_serial_write_t serial)
|
||||
m_serial_json_write_variant_end(m_serial_local_t local, m_serial_write_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE *)serial->data[0].p;
|
||||
int n = fprintf(f, "}");
|
||||
return n > 0 ? M_SERIAL_OK_DONE : M_SERIAL_FAIL;
|
||||
@@ -300,8 +314,9 @@ m_serial_json_read_string(m_serial_read_t serial, struct string_s *s){
|
||||
}
|
||||
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_read_array_start(m_serial_read_t serial, size_t *num)
|
||||
m_serial_json_read_array_start(m_serial_local_t local, m_serial_read_t serial, size_t *num)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
int final1 = -1, final2 = -1;
|
||||
fscanf(f, " [%n ]%n", &final1, &final2);
|
||||
@@ -311,8 +326,9 @@ m_serial_json_read_array_start(m_serial_read_t serial, size_t *num)
|
||||
}
|
||||
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_read_array_next(m_serial_read_t serial)
|
||||
m_serial_json_read_array_next(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
char c = 0;
|
||||
fscanf(f, " %c", &c);
|
||||
@@ -320,8 +336,9 @@ m_serial_json_read_array_next(m_serial_read_t serial)
|
||||
}
|
||||
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_read_map_start(m_serial_read_t serial, size_t *num)
|
||||
m_serial_json_read_map_start(m_serial_local_t local, m_serial_read_t serial, size_t *num)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
int final1 = -1, final2 = -1;
|
||||
fscanf(f, " {%n }%n", &final1, &final2);
|
||||
@@ -331,8 +348,9 @@ m_serial_json_read_map_start(m_serial_read_t serial, size_t *num)
|
||||
}
|
||||
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_read_map_value(m_serial_read_t serial)
|
||||
m_serial_json_read_map_value(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
int final = -1;
|
||||
fscanf(f, " :%n", &final);
|
||||
@@ -340,8 +358,9 @@ m_serial_json_read_map_value(m_serial_read_t serial)
|
||||
}
|
||||
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_read_map_next(m_serial_read_t serial)
|
||||
m_serial_json_read_map_next(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
char c = 0;
|
||||
fscanf(f, " %c", &c);
|
||||
@@ -349,8 +368,9 @@ m_serial_json_read_map_next(m_serial_read_t serial)
|
||||
}
|
||||
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_read_tuple_start(m_serial_read_t serial)
|
||||
m_serial_json_read_tuple_start(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
int final = -1;
|
||||
fscanf(f, " {%n", &final);
|
||||
@@ -358,7 +378,9 @@ m_serial_json_read_tuple_start(m_serial_read_t serial)
|
||||
}
|
||||
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_read_tuple_id(m_serial_read_t serial, const char *const field_name [], const int max, int *id){
|
||||
m_serial_json_read_tuple_id(m_serial_local_t local, m_serial_read_t serial, const char *const field_name [], const int max, int *id)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
int c = m_serial_json_read_skip(f);
|
||||
if (c == EOF) return M_SERIAL_FAIL;
|
||||
@@ -387,8 +409,9 @@ m_serial_json_read_tuple_id(m_serial_read_t serial, const char *const field_name
|
||||
}
|
||||
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_read_variant_start(m_serial_read_t serial, const char *const field_name[], const int max, int*id)
|
||||
m_serial_json_read_variant_start(m_serial_local_t local, m_serial_read_t serial, const char *const field_name[], const int max, int*id)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
|
||||
int final1 = -1, final2 = -1;
|
||||
@@ -413,8 +436,9 @@ m_serial_json_read_variant_start(m_serial_read_t serial, const char *const field
|
||||
}
|
||||
|
||||
static inline m_serial_return_code_t
|
||||
m_serial_json_read_variant_end(m_serial_read_t serial)
|
||||
m_serial_json_read_variant_end(m_serial_local_t local, m_serial_read_t serial)
|
||||
{
|
||||
(void) local; // argument not used
|
||||
FILE *f = (FILE*) serial->data[0].p;
|
||||
int final = -1;
|
||||
fscanf(f, " }%n", &final);
|
||||
|
||||
@@ -419,15 +419,16 @@ namespace m_tuple {
|
||||
static const char *const field_name[] = \
|
||||
{ M_REDUCE(TUPLE_STRINGIFY_NAME, M_ID, __VA_ARGS__) }; \
|
||||
int index = 0; \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
ret = f->interface->write_tuple_start(f); \
|
||||
ret = f->interface->write_tuple_start(local, f); \
|
||||
M_MAP(TUPLE_DEFINE_OUT_SERIAL_FUNC , __VA_ARGS__) \
|
||||
assert( index == field_max); \
|
||||
ret |= f->interface->write_tuple_end(f); \
|
||||
ret |= f->interface->write_tuple_end(local, f); \
|
||||
return ret & M_SERIAL_FAIL; \
|
||||
}
|
||||
#define TUPLE_DEFINE_OUT_SERIAL_FUNC(a) \
|
||||
f->interface->write_tuple_id(f, field_name, field_max, index); \
|
||||
f->interface->write_tuple_id(local, f, field_name, field_max, index); \
|
||||
TUPLE_CALL_OUT_SERIAL(a, f, el -> TUPLE_GET_FIELD a); \
|
||||
index++; \
|
||||
|
||||
@@ -439,10 +440,11 @@ namespace m_tuple {
|
||||
const int field_max = M_NARGS(__VA_ARGS__); \
|
||||
static const char *const field_name[] = \
|
||||
{ M_REDUCE(TUPLE_STRINGIFY_NAME, M_ID, __VA_ARGS__) }; \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
ret = f->interface->read_tuple_start(f); \
|
||||
ret = f->interface->read_tuple_start(local, f); \
|
||||
while (ret == M_SERIAL_OK_CONTINUE) { \
|
||||
ret = f->interface->read_tuple_id(f, field_name, field_max, &index); \
|
||||
ret = f->interface->read_tuple_id(local, f, field_name, field_max, &index); \
|
||||
if (ret == M_SERIAL_OK_CONTINUE) { \
|
||||
assert (index >= 0 && index < field_max); \
|
||||
switch (1+index) { \
|
||||
|
||||
+7
-5
@@ -513,20 +513,21 @@
|
||||
static const char *const field_name[] = \
|
||||
{ M_REDUCE(VARIANTI_STRINGIFY_NAME, M_ID, __VA_ARGS__) }; \
|
||||
assert (f != NULL && f->interface != NULL && el != NULL); \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
switch (el->type) { \
|
||||
case M_C(name, _EMPTY): \
|
||||
return f->interface->write_variant_start(f, field_name, field_max, -1); \
|
||||
return f->interface->write_variant_start(local, f, field_name, field_max, -1); \
|
||||
break; \
|
||||
M_MAP2(VARIANTI_DEFINE_OUT_SERIAL_FUNC , name, __VA_ARGS__) \
|
||||
default: assert(false); break; \
|
||||
} \
|
||||
ret |= f->interface->write_variant_end(f); \
|
||||
ret |= f->interface->write_variant_end(local, f); \
|
||||
return ret & M_SERIAL_FAIL; \
|
||||
}
|
||||
#define VARIANTI_DEFINE_OUT_SERIAL_FUNC(name, a) \
|
||||
case M_C4(name, _, VARIANTI_GET_FIELD a, _value): \
|
||||
ret = f->interface->write_variant_start(f, field_name, field_max, \
|
||||
ret = f->interface->write_variant_start(local, f, field_name, field_max, \
|
||||
M_C4(name, _, VARIANTI_GET_FIELD a, _value) -1); \
|
||||
VARIANTI_CALL_OUT_SERIAL(a, f, el -> value . VARIANTI_GET_FIELD a); \
|
||||
break;
|
||||
@@ -540,10 +541,11 @@
|
||||
static const char *const field_name[] = \
|
||||
{ M_REDUCE(VARIANTI_STRINGIFY_NAME, M_ID, __VA_ARGS__) }; \
|
||||
assert (f != NULL && f->interface != NULL && el != NULL); \
|
||||
m_serial_local_t local; \
|
||||
m_serial_return_code_t ret; \
|
||||
int id = -1; \
|
||||
M_C(name, _clean)(el); \
|
||||
ret = f->interface->read_variant_start(f, field_name, field_max, &id); \
|
||||
ret = f->interface->read_variant_start(local, f, field_name, field_max, &id); \
|
||||
if (ret != M_SERIAL_OK_CONTINUE) return ret; \
|
||||
assert (id >= 0 && id < field_max); \
|
||||
el->type = id+1; \
|
||||
@@ -552,7 +554,7 @@
|
||||
default: assert(false); break; \
|
||||
} \
|
||||
if (ret == M_SERIAL_OK_DONE) \
|
||||
ret = f->interface->read_variant_end(f); \
|
||||
ret = f->interface->read_variant_end(local, f); \
|
||||
return ret; \
|
||||
}
|
||||
#define VARIANTI_DEFINE_IN_SERIAL_FUNC(name, a) \
|
||||
|
||||
Reference in new issue
Block a user