diff --git a/m-core.h b/m-core.h index 0c11c97e..c61bb18b 100644 --- a/m-core.h +++ b/m-core.h @@ -1373,6 +1373,14 @@ /* C11 MACROS */ +/* Maximum number of characters of an internal identifier + including final null char. Bigger than + 63 significant initial characters of C11 standard (ยง5.2.4.1) + Can be overloaded by user if needed. */ +#ifndef M_MAX_IDENTIFIER_LENGTH +#define M_MAX_IDENTIFIER_LENGTH 128 /* (including of final null char) */ +#endif + /* Return the string format of a variable */ #define M_PRINTF_FORMAT(x) \ _Generic(((void)0,(x)), \ diff --git a/m-serial-json.h b/m-serial-json.h index 2956b0c6..2803c96b 100644 --- a/m-serial-json.h +++ b/m-serial-json.h @@ -199,8 +199,31 @@ m_serial_json_read_tuple_id(m_serial_read_t serial, const char *const field_name FILE *f = (FILE*) serial->data[0]; int c = m_serial_json_read_skip(f); if (c == '}') return M_SERIAL_OK_DONE; + if (c == ',') { + // If first call of read_tuple_id, it is a failure + if (*id == -1) return M_SERIAL_FAIL; + c = m_serial_json_read_skip(f); + } if (c != '"') return M_SERIAL_FAIL; - + /* Read the field in the JSON */ + char field[M_MAX_IDENTIFIER_LENGTH]; + int n = 0; + do { + c =fgetc(f); + field[n++] = c; + } while (n < M_MAX_IDENTIFIER_LENGTH && c != EOF && c != '\"'); + field[--n] = 0; + if (c != '"') return M_SERIAL_FAIL; + c =fgetc(f); + if (c != ':') return M_SERIAL_FAIL; + /* Search for field in field_name */ + for(n = 0; n < max; n++) { + if (strcmp(field, field_name[n]) == 0) + break; + } + if (n == max) return M_SERIAL_FAIL; + *id = n; + return M_SERIAL_OK_CONTINUE; } 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){ return M_SERIAL_FAIL; } diff --git a/m-tuple.h b/m-tuple.h index 787324cc..6a559617 100644 --- a/m-tuple.h +++ b/m-tuple.h @@ -435,19 +435,20 @@ namespace m_tuple { static inline m_serial_return_code_t \ M_C(name, _in_serial)(M_C(name,_t) el, m_serial_read_t f) { \ assert (f != NULL && el != NULL); \ - int index = 0; \ + int index = -1; \ const int field_max = M_NARGS(__VA_ARGS__); \ static const char *const field_name[] = \ - { M_MAP(TUPLE_STRINGIFY_NAME, __VA_ARGS__) }; \ + { M_REDUCE(TUPLE_STRINGIFY_NAME, M_ID, __VA_ARGS__) }; \ m_serial_return_code_t ret; \ ret = f->interface->read_tuple_start(f); \ - while (ret != M_SERIAL_OK_CONTINUE) { \ + while (ret == M_SERIAL_OK_CONTINUE) { \ ret = f->interface->read_tuple_id(f, field_name, field_max, &index); \ if (ret == M_SERIAL_OK_CONTINUE) { \ switch (1+index) { \ M_MAP2(TUPLE_DEFINE_IN_SERIAL_FUNC , name, __VA_ARGS__) \ default: assert(0); \ } \ + ret = (ret == M_SERIAL_OK_DONE) ? M_SERIAL_OK_CONTINUE : M_SERIAL_FAIL; \ } \ } \ return ret; \