diff --git a/fx.serial/bitcode.c b/fx.serial/bitcode.c index ff8bd3a..9c2bf67 100644 --- a/fx.serial/bitcode.c +++ b/fx.serial/bitcode.c @@ -5,7 +5,7 @@ static struct fx_error *bitcode_serialise( fx_serial_ctx *serial, - fx_object *src, + const fx_value *src, fx_stream *dest, enum fx_serial_flags flags) { @@ -15,7 +15,7 @@ static struct fx_error *bitcode_serialise( static struct fx_error *bitcode_deserialise( fx_serial_ctx *serial, fx_stream *src, - fx_object **dest, + fx_value *dest, enum fx_serial_flags flags) { return FX_RESULT_ERR(NOT_SUPPORTED); diff --git a/fx.serial/ctx.c b/fx.serial/ctx.c index 0528a6e..37aa0dc 100644 --- a/fx.serial/ctx.c +++ b/fx.serial/ctx.c @@ -44,7 +44,7 @@ FX_TYPE_DEFINITION_END(fx_serial_ctx) fx_result fx_serial_ctx_serialise( fx_serial_ctx *ctx, - fx_object *src, + const fx_value *src, fx_stream *dest, enum fx_serial_flags flags) { @@ -62,7 +62,7 @@ fx_result fx_serial_ctx_serialise( fx_result fx_serial_ctx_deserialise( fx_serial_ctx *ctx, fx_stream *src, - fx_object **dest, + fx_value *dest, enum fx_serial_flags flags) { FX_CLASS_DISPATCH_VIRTUAL( diff --git a/fx.serial/include/fx/serial/ctx.h b/fx.serial/include/fx/serial/ctx.h index 1c410a5..27b01b4 100644 --- a/fx.serial/include/fx/serial/ctx.h +++ b/fx.serial/include/fx/serial/ctx.h @@ -6,6 +6,7 @@ #include #include #include +#include FX_DECLS_BEGIN; @@ -21,13 +22,13 @@ FX_DECLARE_TYPE(fx_serial_ctx); FX_TYPE_CLASS_DECLARATION_BEGIN(fx_serial_ctx) fx_result (*s_serialise)( fx_serial_ctx *, - fx_object *, + const fx_value *, fx_stream *, fx_serial_flags); fx_result (*s_deserialise)( fx_serial_ctx *, fx_stream *, - fx_object **, + fx_value *, fx_serial_flags); FX_TYPE_CLASS_DECLARATION_END(fx_serial_ctx) @@ -39,14 +40,14 @@ FX_API fx_type_id fx_serial_ctx_get_type(void); FX_API fx_result fx_serial_ctx_serialise( fx_serial_ctx *ctx, - fx_object *src, + const fx_value *src, fx_stream *dest, fx_serial_flags flags); FX_API fx_result fx_serial_ctx_deserialise( fx_serial_ctx *ctx, fx_stream *src, - fx_object **dest, + fx_value *dest, fx_serial_flags flags); FX_DECLS_END; diff --git a/fx.serial/test/toml-decode.c b/fx.serial/test/toml-decode.c index 63adb45..8b2b449 100644 --- a/fx.serial/test/toml-decode.c +++ b/fx.serial/test/toml-decode.c @@ -1,24 +1,26 @@ #include #include -#include +#include +#include #include #include #include #include #include #include +#include -void write_tagged_value(fx_object *data); +void write_tagged_value(const fx_value *data); void write_raw_string(const fx_string *data) { fx_stream_write_cstr(fx_stdout, "\"", NULL); - const fx_iterator *it = fx_iterator_cbegin(data); + const fx_iterator *it = fx_iterator_begin(data); fx_foreach(val, it) { fx_wchar c; - fx_value_get_wchar(&val, &c); + fx_value_get_wchar(val, &c); if (c >= 0x10000) { c -= 0x10000; long hi = 0xD800 | ((c >> 10) & 0x3FF); @@ -54,75 +56,49 @@ void write_tagged_string(fx_string *data) fx_stream_write_cstr(fx_stdout, " }", NULL); } -void write_tagged_integer(fx_int *data) +void write_tagged_integer(const fx_value *data) { -#if 0 fx_stream_write_cstr( fx_stdout, "{ \"type\": \"integer\", \"value\": \"", NULL); - - if (fx_int_is_inf_positive(data)) { - fx_stream_write_cstr(fx_stdout, "inf", NULL); - } else if (fx_int_is_inf_negative(data)) { - fx_stream_write_cstr(fx_stdout, "-inf", NULL); - } else if (fx_int_is_nan_positive(data)) { - fx_stream_write_cstr(fx_stdout, "nan", NULL); - } else if (fx_int_is_nan_negative(data)) { - fx_stream_write_cstr(fx_stdout, "-nan", NULL); - } else { - fx_stream_write_fmt( - fx_stdout, - NULL, - "%lld", - fx_int_get_value(data), - NULL); - } - + fx_stream_write_fmt(fx_stdout, NULL, "%lld", data->v_i64, NULL); fx_stream_write_cstr(fx_stdout, "\" }", NULL); -#endif } -void write_tagged_float(fx_double *data) +void write_tagged_float(const fx_value *data) { -#if 0 fx_stream_write_cstr( fx_stdout, "{ \"type\": \"float\", \"value\": \"", NULL); - if (fx_double_is_inf_positive(data)) { + double d = data->v_double; + if (d == INFINITY) { fx_stream_write_cstr(fx_stdout, "inf", NULL); - } else if (fx_double_is_inf_negative(data)) { + } else if (d == -INFINITY) { fx_stream_write_cstr(fx_stdout, "-inf", NULL); - } else if (fx_double_is_nan_positive(data)) { + } else if (d == NAN) { fx_stream_write_cstr(fx_stdout, "nan", NULL); - } else if (fx_double_is_nan_negative(data)) { + } else if (d == -NAN) { fx_stream_write_cstr(fx_stdout, "-nan", NULL); + } else if (d <= 1e-9 || d >= 1e9) { + fx_stream_write_fmt(fx_stdout, NULL, "%g", d, NULL); } else { - double v = fx_double_get_value(data); - if ((v <= 0.00000001 && v > 0) || (v >= -0.00000001 && v < 0) - || (v >= 1000000000) || (v <= -1000000000)) { - fx_stream_write_fmt(fx_stdout, NULL, "%.15e", v, NULL); - } else { - fx_stream_write_fmt(fx_stdout, NULL, "%.15f", v, NULL); - } + fx_stream_write_fmt(fx_stdout, NULL, "%.9lf", d, NULL); } fx_stream_write_cstr(fx_stdout, "\" }", NULL); -#endif } -void write_tagged_bool(fx_bool *data) +void write_tagged_bool(const fx_value *data) { -#if 0 fx_stream_write_fmt( fx_stdout, NULL, "{ \"type\": \"bool\", \"value\": \"%s\" }", - fx_bool_get_value(data) ? "true" : "false", + data->v_bool ? "true" : "false", NULL); -#endif } void write_tagged_datetime(fx_datetime *data) @@ -152,75 +128,78 @@ void write_tagged_datetime(fx_datetime *data) fx_stream_write_cstr(fx_stdout, "\", \"value\": \"", NULL); - fx_string *new_data = fx_string_create(); + fx_stringstream *new_data = fx_stringstream_create(); fx_datetime_to_string(data, FX_DATETIME_FORMAT_RFC3339, new_data); - fx_stream_write_cstr(fx_stdout, fx_string_get_cstr(new_data), NULL); + fx_stream_write_cstr(fx_stdout, fx_stringstream_ptr(new_data), NULL); fx_stream_write_cstr(fx_stdout, "\" }", NULL); - fx_string_unref(new_data); + fx_stringstream_unref(new_data); } -#if 0 -void write_tagged_dict(fx_dict *data) +void write_tagged_hashtable(fx_hashtable *data) { fx_stream_write_cstr(fx_stdout, "{ ", NULL); int i = 0; - fx_iterator *it = fx_iterator_begin(data); - fx_foreach(fx_dict_item *, item, it) + const fx_iterator *it = fx_iterator_begin(data); + fx_foreach(v, it) { + fx_hashtable_item *item; + fx_value_get_object(v, &item); if (i++ > 0) { fx_stream_write_cstr(fx_stdout, ", ", NULL); } - write_raw_string(item->key); + const fx_value *key = fx_hashtable_item_get_key(item); + const fx_value *value = fx_hashtable_item_get_value(item); + fx_string *key_str; + fx_value_get_object(key, &key_str); + write_raw_string(key_str); fx_stream_write_cstr(fx_stdout, ": ", NULL); - write_tagged_value(item->value); + write_tagged_value(value); } fx_iterator_unref(it); fx_stream_write_cstr(fx_stdout, " }", NULL); } -#endif void write_tagged_array(fx_array *data) { fx_stream_write_cstr(fx_stdout, "[ ", NULL); int i = 0; - fx_iterator *it = fx_iterator_begin(data); + const fx_iterator *it = fx_iterator_begin(data); fx_foreach(val, it) { - fx_object *obj; - fx_value_get_object(&val, &obj); if (i++ > 0) { fx_stream_write_cstr(fx_stdout, ", ", NULL); } - write_tagged_value(obj); + write_tagged_value(val); } fx_iterator_unref(it); fx_stream_write_cstr(fx_stdout, " ]", NULL); } -void write_tagged_value(fx_object *data) +void write_tagged_value(const fx_value *data) { -#if 0 - if (fx_object_is_type(data, FX_TYPE_DICT)) { - write_tagged_dict(data); - } else -#endif - if (fx_object_is_type(data, FX_TYPE_ARRAY)) { - write_tagged_array(data); - } else if (fx_object_is_type(data, FX_TYPE_STRING)) { - write_tagged_string(data); - } else if (fx_object_is_type(data, FX_TYPE_DATETIME)) { - write_tagged_datetime(data); - } else if (fx_object_is_type(data, FX_TYPE_BOOL)) { + if (fx_value_is_type(data, FX_TYPE_HASHTABLE)) { + write_tagged_hashtable(data->v_object); + } else if (fx_value_is_type(data, FX_TYPE_ARRAY)) { + write_tagged_array(data->v_object); + } else if (fx_value_is_type(data, FX_TYPE_STRING)) { + write_tagged_string(data->v_object); + } else if (fx_value_is_type(data, FX_TYPE_DATETIME)) { + write_tagged_datetime(data->v_object); + } else if (fx_value_is_type(data, FX_TYPE_BOOL)) { write_tagged_bool(data); + } else if (fx_value_is_type(data, FX_TYPE_I64)) { + write_tagged_integer(data); + } else if (fx_value_is_type(data, FX_TYPE_DOUBLE)) { + write_tagged_float(data); } } @@ -231,19 +210,18 @@ int main(void) fx_serial_ctx *ctx = fx_toml_serial_ctx_create(); - fx_object *data; + fx_value data; fx_result result = fx_serial_ctx_deserialise(ctx, src, &data, 0); if (fx_result_is_error(result)) { - fx_throw(result); - return -1; + return 1; } - write_tagged_value(data); + write_tagged_value(&data); fx_stream_write_char(fx_stdout, '\n'); fx_serial_ctx_unref(ctx); - fx_object_unref(data); + fx_value_unset(&data); return 0; } diff --git a/fx.serial/toml.c b/fx.serial/toml.c index 3b3b23b..753e55f 100644 --- a/fx.serial/toml.c +++ b/fx.serial/toml.c @@ -1,8 +1,8 @@ #include #include -#include #include #include +#include #include #include #include @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -116,9 +117,9 @@ struct ctx { fx_stream *ctx_src; fx_string *ctx_wordbuf; fx_string *ctx_linebuf; - fx_iterator *ctx_linebuf_ptr; + const fx_iterator *ctx_linebuf_ptr; fx_result ctx_result; - fx_hashmap *ctx_objects_flags; + fx_hashtable *ctx_objects_flags; fx_queue ctx_tokens; }; @@ -132,29 +133,18 @@ static void ctx_set_object_flags( return; } - fx_hashmap_key key = { - .key_data = obj, - .key_size = sizeof(fx_object *), - .key_flags = FX_HASHMAP_KEY_F_INTVALUE, - }; - - const fx_hashmap_value *old_value = fx_hashmap_get( - ctx->ctx_objects_flags, - &key); + fx_value ptr = FX_POINTER(obj); + const fx_value *old_value + = fx_hashtable_get(ctx->ctx_objects_flags, &ptr); enum object_flags new_flags = 0; if (old_value) { - new_flags = (enum object_flags)(uintptr_t)old_value->value_data; + new_flags = (enum object_flags)old_value->v_i32; } new_flags |= flags; - fx_hashmap_value value = { - .value_data = (void *)new_flags, - .value_size = sizeof new_flags, - }; - - fx_hashmap_put(ctx->ctx_objects_flags, &key, &value); + fx_hashtable_put(ctx->ctx_objects_flags, &ptr, &FX_I32(new_flags)); } static void ctx_clear_object_flags( @@ -166,29 +156,18 @@ static void ctx_clear_object_flags( return; } - fx_hashmap_key key = { - .key_data = obj, - .key_size = sizeof(fx_object *), - .key_flags = FX_HASHMAP_KEY_F_INTVALUE, - }; - - const fx_hashmap_value *old_value = fx_hashmap_get( - ctx->ctx_objects_flags, - &key); + fx_value ptr = FX_POINTER(obj); + const fx_value *old_value + = fx_hashtable_get(ctx->ctx_objects_flags, &ptr); enum object_flags new_flags = 0; if (old_value) { - new_flags = (enum object_flags)(uintptr_t)old_value->value_data; + new_flags = (enum object_flags)old_value->v_i32; } new_flags &= ~mask; - fx_hashmap_value value = { - .value_data = (void *)new_flags, - .value_size = sizeof new_flags, - }; - - fx_hashmap_put(ctx->ctx_objects_flags, &key, &value); + fx_hashtable_put(ctx->ctx_objects_flags, &ptr, &FX_I32(new_flags)); } static enum object_flags ctx_get_object_flags(struct ctx *ctx, fx_object *obj) @@ -197,17 +176,13 @@ static enum object_flags ctx_get_object_flags(struct ctx *ctx, fx_object *obj) return 0; } - fx_hashmap_key key = { - .key_data = obj, - .key_size = sizeof(fx_object *), - .key_flags = FX_HASHMAP_KEY_F_INTVALUE, - }; + fx_value ptr = FX_POINTER(obj); + const fx_value *old_value + = fx_hashtable_get(ctx->ctx_objects_flags, &ptr); - const fx_hashmap_value *value = fx_hashmap_get( - ctx->ctx_objects_flags, - &key); - if (value) { - return (enum object_flags)(uintptr_t)value->value_data; + enum object_flags new_flags = 0; + if (old_value) { + return (enum object_flags)old_value->v_i32; } return 0; @@ -297,7 +272,7 @@ static fx_wchar advance_char(struct ctx *ctx) const char *s = fx_string_get_cstr(ctx->ctx_linebuf); - fx_wchar c = fx_iterator_get_value(ctx->ctx_linebuf_ptr).v_int; + fx_wchar c = fx_iterator_get_value(ctx->ctx_linebuf_ptr)->v_wchar; if (!is_valid_char(c)) { ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); @@ -330,7 +305,7 @@ static fx_wchar peek_char(struct ctx *ctx) const char *s = fx_string_get_cstr(ctx->ctx_linebuf); - fx_wchar c = fx_iterator_get_value(ctx->ctx_linebuf_ptr).v_int; + fx_wchar c = fx_iterator_get_value(ctx->ctx_linebuf_ptr)->v_wchar; if (!is_valid_char(c)) { ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); @@ -929,7 +904,7 @@ static void split_word(struct ctx *ctx, fx_string *wordbuf) fx_foreach(tokv, it) { const char *tok = NULL; - fx_value_get_cstr(&tokv, &tok); + fx_value_get_cstr(tokv, &tok); if (i > 0) { enqueue_token(ctx, TOK_DOT); @@ -1032,11 +1007,11 @@ static void read_word(struct ctx *ctx) return; } - fx_iterator *it = fx_iterator_begin(wordbuf); + const fx_iterator *it = fx_iterator_begin(wordbuf); fx_foreach(cv, it) { fx_wchar c = FX_WCHAR_INVALID; - fx_value_get_wchar(&cv, &c); + fx_value_get_wchar(cv, &c); /* only allow ASCII numbers/letters here */ bool ok = isalnum(c) || c == '_' || c == '-' || c == '.'; if (!ok) { @@ -1184,8 +1159,8 @@ static void read_string(struct ctx *ctx, bool squote) } if (c != '\n') { - ctx->ctx_result = FX_RESULT_ERR( - BAD_FORMAT); + ctx->ctx_result + = FX_RESULT_ERR(BAD_FORMAT); fail = true; break; } @@ -1230,18 +1205,16 @@ static void read_string(struct ctx *ctx, bool squote) case 'U': c = read_unicode_sequence(ctx); if (c == FX_WCHAR_INVALID) { - ctx->ctx_result = FX_RESULT_ERR( - BAD_FORMAT); + ctx->ctx_result + = FX_RESULT_ERR(BAD_FORMAT); fail = true; break; } - ctx->ctx_result = FX_OK(fx_string_append_wc( - str, - c)) - ? FX_SUCCESS - : FX_RESULT_ERR( - BAD_FORMAT); + ctx->ctx_result + = FX_OK(fx_string_append_wc(str, c)) + ? FX_SUCCESS + : FX_RESULT_ERR(BAD_FORMAT); fail = !FX_OK(ctx->ctx_result); break; default: @@ -1482,14 +1455,24 @@ static fx_result advance_token(struct ctx *ctx) start: c = peek_char(ctx); - while (isspace(c) && c != '\n' && c != '\r') { - advance_char(ctx); - c = peek_char(ctx); + + if (c <= 0) { + if (fx_error_get_status_code(ctx->ctx_result) + == FX_ERR_NO_DATA) { + ctx->ctx_flags |= CTX_EOF; + } + + return ctx->ctx_result; } - if (c == -1) { - ctx->ctx_flags |= CTX_EOF; - return FX_RESULT_ERR(NO_DATA); + if (c <= 31 && c != '\n' && c != '\r' && c != '\t') { + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); + return ctx->ctx_result; + } + + while (fx_wchar_is_space(c) && c != '\n' && c != '\r') { + advance_char(ctx); + c = peek_char(ctx); } #if 1 @@ -1559,7 +1542,7 @@ static void ctx_cleanup(struct ctx *ctx) } if (ctx->ctx_objects_flags) { - fx_hashmap_unref(ctx->ctx_objects_flags); + fx_hashtable_unref(ctx->ctx_objects_flags); ctx->ctx_objects_flags = NULL; } } @@ -1571,14 +1554,14 @@ static fx_result ctx_init(struct ctx *ctx) ctx->ctx_linebuf = fx_string_create(); ctx->ctx_wordbuf = fx_string_create(); - ctx->ctx_objects_flags = fx_hashmap_create(NULL, NULL); + ctx->ctx_objects_flags = fx_hashtable_create(); return FX_RESULT_SUCCESS; } static fx_result toml_serialise( fx_serial_ctx *serial, - fx_object *src, + const fx_value *src, fx_stream *dest, enum fx_serial_flags flags) { @@ -1672,20 +1655,20 @@ static void print_token(struct token *tok) } } -static fx_result parse_value(struct ctx *ctx, fx_object **result); +static fx_result parse_value(struct ctx *ctx, fx_value *result); static fx_result parse_key_value_pair(struct ctx *ctx, fx_hashtable *container); -static fx_result parse_timestamp(struct ctx *ctx, fx_object **result) +static fx_result parse_timestamp(struct ctx *ctx, fx_value *result) { struct token *tok = peek_token(ctx); fx_datetime *dt = tok->tok_value.time; tok->tok_value.time = NULL; - *result = (dt); + *result = FX_VALUE_OBJECT(dt); return FX_RESULT_SUCCESS; } -static fx_result parse_string(struct ctx *ctx, fx_object **result) +static fx_result parse_string(struct ctx *ctx, fx_value *result) { struct token *tok = peek_token(ctx); fx_string *str = fx_string_duplicate(tok->tok_str); @@ -1693,81 +1676,48 @@ static fx_result parse_string(struct ctx *ctx, fx_object **result) return FX_RESULT_ERR(NO_MEMORY); } - *result = (str); + *result = FX_VALUE_OBJECT(str); return FX_RESULT_SUCCESS; } -static fx_result parse_int(struct ctx *ctx, fx_object **result) +static fx_result parse_int(struct ctx *ctx, fx_value *result) { -#if 0 struct token *tok = peek_token(ctx); - fx_int *val = fx_int_create(tok->tok_value.i.v); - if (!val) { - return FX_RESULT_ERR(NO_MEMORY); - } - - if (tok->tok_value.i.inf) { - if (tok->tok_value.i.v >= 0) { - fx_int_set_value_inf(val); - } else { - fx_int_set_value_inf_negative(val); - } - } else if (tok->tok_value.i.nan) { - if (tok->tok_value.i.v >= 0) { - fx_int_set_value_nan(val); - } else { - fx_int_set_value_nan_negative(val); - } - } - - *result = (val); -#endif + *result = FX_I64(tok->tok_value.i.v); return FX_RESULT_SUCCESS; } -static fx_result parse_float(struct ctx *ctx, fx_object **result) +static fx_result parse_float(struct ctx *ctx, fx_value *result) { -#if 0 struct token *tok = peek_token(ctx); - fx_double *val = fx_double_create(tok->tok_value.f.v); - if (!val) { - return FX_RESULT_ERR(NO_MEMORY); - } if (tok->tok_value.f.inf) { if (tok->tok_value.f.v >= 0) { - fx_double_set_value_inf(val); + *result = FX_DOUBLE(INFINITY); } else { - fx_double_set_value_inf_negative(val); + *result = FX_DOUBLE(-INFINITY); } } else if (tok->tok_value.f.nan) { if (tok->tok_value.f.v >= 0) { - fx_double_set_value_nan(val); + *result = FX_DOUBLE(NAN); } else { - fx_double_set_value_nan_negative(val); + *result = FX_DOUBLE(-NAN); } + } else { + *result = FX_DOUBLE(tok->tok_value.f.v); } - *result = (val); -#endif return FX_RESULT_SUCCESS; } -static fx_result parse_bool(struct ctx *ctx, fx_object **result) +static fx_result parse_bool(struct ctx *ctx, fx_value *result) { -#if 0 struct token *tok = peek_token(ctx); - fx_bool *val = fx_bool_create(tok->tok_value.b); - if (!val) { - return FX_RESULT_ERR(NO_MEMORY); - } - - *result = (val); -#endif + *result = FX_BOOL(tok->tok_value.b); return FX_RESULT_SUCCESS; } -static fx_result parse_table_inline(struct ctx *ctx, fx_object **result) +static fx_result parse_table_inline(struct ctx *ctx, fx_value *result) { DISABLE_EXTENDED_LEXING(ctx); @@ -1780,7 +1730,7 @@ static fx_result parse_table_inline(struct ctx *ctx, fx_object **result) struct token *tok = peek_token(ctx); if (tok && tok->tok_type == TOK_RIGHT_BRACE) { - *result = (table); + *result = FX_VALUE_OBJECT(table); return FX_RESULT_SUCCESS; } @@ -1814,7 +1764,7 @@ static fx_result parse_table_inline(struct ctx *ctx, fx_object **result) } } - *result = (table); + *result = FX_VALUE_OBJECT(table); return FX_RESULT_SUCCESS; } @@ -1828,7 +1778,7 @@ static void skip_newlines(struct ctx *ctx) } } -static fx_result parse_array_inline(struct ctx *ctx, fx_object **result) +static fx_result parse_array_inline(struct ctx *ctx, fx_value *result) { bool done = false; ENABLE_EXTENDED_LEXING(ctx); @@ -1865,16 +1815,15 @@ static fx_result parse_array_inline(struct ctx *ctx, fx_object **result) break; } - fx_object *value; + fx_value value; fx_result status = parse_value(ctx, &value); if (!FX_OK(status)) { fx_array_unref(array); return status; } -#if 0 - fx_array_append(array, FX_RV(value)); -#endif + fx_array_push_back(array, value); + fx_value_unset(&value); ENABLE_EXTENDED_LEXING(ctx); advance_token(ctx); @@ -1897,11 +1846,11 @@ static fx_result parse_array_inline(struct ctx *ctx, fx_object **result) } DISABLE_EXTENDED_LEXING(ctx); - *result = (array); + *result = FX_VALUE_OBJECT(array); return FX_RESULT_SUCCESS; } -static fx_result parse_value(struct ctx *ctx, fx_object **result) +static fx_result parse_value(struct ctx *ctx, fx_value *result) { struct token *tok = peek_token(ctx); @@ -1948,9 +1897,13 @@ static fx_result parse_key_value_pair(struct ctx *ctx, fx_hashtable *container) } while (tok && tok->tok_type == TOK_DOT) { - const fx_value *child = fx_hashtable_get( - container, - &FX_VALUE_OBJECT(key)); + const fx_value *child + = fx_hashtable_get(container, &FX_VALUE_OBJECT(key)); + if (child && !fx_value_is_type(child, FX_TYPE_HASHTABLE)) { + fx_string_unref(key); + return FX_RESULT_ERR(BAD_FORMAT); + } + fx_hashmap *subtable = NULL; fx_value_get_object(child, &subtable); if (!subtable) { @@ -1959,18 +1912,13 @@ static fx_result parse_key_value_pair(struct ctx *ctx, fx_hashtable *container) container, &FX_VALUE_OBJECT(key), &FX_VALUE_OBJECT(subtable)); - } else if ( - subtable - && !fx_object_is_type(subtable, FX_TYPE_HASHTABLE)) { - free(key); - return FX_RESULT_ERR(BAD_FORMAT); } #if 1 enum object_flags flags = ctx_get_object_flags(ctx, subtable); if (flags & (OBJECT_KV_END_DEFINED | OBJECT_HEADER_END_DEFINED)) { - free(key); + fx_string_unref(key); return FX_RESULT_ERR(BAD_FORMAT); } #endif @@ -1980,7 +1928,7 @@ static fx_result parse_key_value_pair(struct ctx *ctx, fx_hashtable *container) advance_token(ctx); tok = peek_token(ctx); if (!IS_VALID_KEY_COMPONENT(tok)) { - free(key); + fx_string_unref(key); return FX_RESULT_ERR(BAD_FORMAT); } @@ -2010,7 +1958,7 @@ static fx_result parse_key_value_pair(struct ctx *ctx, fx_hashtable *container) ENABLE_EXTENDED_LEXING(ctx); advance_token(ctx); - fx_object *value = NULL; + fx_value value = FX_VALUE_EMPTY; fx_result result = parse_value(ctx, &value); DISABLE_EXTENDED_LEXING(ctx); @@ -2025,17 +1973,17 @@ static fx_result parse_key_value_pair(struct ctx *ctx, fx_hashtable *container) return fx_result_propagate(result); } - fx_hashtable_put( - container, - &FX_VALUE_OBJECT(key), - &FX_VALUE_OBJECT(value)); - fx_object_unref(value); + fx_hashtable_put(container, &FX_VALUE_OBJECT(key), &value); - if (fx_object_is_type(value, FX_TYPE_HASHTABLE) - || fx_object_is_type(value, FX_TYPE_ARRAY)) { - ctx_set_object_flags(ctx, value, OBJECT_KV_END_DEFINED); + if (fx_value_is_type(&value, FX_TYPE_HASHTABLE) + || fx_value_is_type(&value, FX_TYPE_ARRAY)) { + ctx_set_object_flags( + ctx, + value.v_object, + OBJECT_KV_END_DEFINED); } + fx_value_unset(&value); return FX_RESULT_SUCCESS; } @@ -2062,26 +2010,24 @@ static fx_result parse_table_header( } while (tok && tok->tok_type == TOK_DOT) { - const fx_value *value = fx_hashtable_get( - container, - &FX_VALUE_OBJECT(key)); + const fx_value *value + = fx_hashtable_get(container, &FX_VALUE_OBJECT(key)); fx_object *subtable = NULL; fx_value_get_object(value, &subtable); enum object_flags flags = ctx_get_object_flags(ctx, subtable); - if (!subtable) { + if (!value) { subtable = (fx_hashtable_create()); fx_hashtable_put( container, &FX_VALUE_OBJECT(key), &FX_VALUE_OBJECT(subtable)); fx_object_unref(subtable); - } else if (fx_object_is_type(subtable, FX_TYPE_ARRAY)) { -#if 0 - subtable = fx_array_at( + } else if (fx_value_is_type(value, FX_TYPE_ARRAY)) { + value = fx_array_get_ref( subtable, - fx_array_size(subtable) - 1); -#endif - } else if (!fx_object_is_type(subtable, FX_TYPE_HASHTABLE)) { + fx_array_get_size(subtable) - 1); + fx_value_get_object(value, &subtable); + } else if (!fx_value_is_type(value, FX_TYPE_HASHTABLE)) { return FX_RESULT_ERR(BAD_FORMAT); } @@ -2112,9 +2058,12 @@ static fx_result parse_table_header( return FX_RESULT_ERR(BAD_FORMAT); } - const fx_value *child = fx_hashtable_get( - container, - &FX_VALUE_OBJECT(key)); + const fx_value *child + = fx_hashtable_get(container, &FX_VALUE_OBJECT(key)); + if (child && !fx_value_is_type(child, FX_TYPE_HASHTABLE)) { + return FX_RESULT_ERR(BAD_FORMAT); + } + fx_hashtable *new_table = NULL; fx_value_get_object(child, &new_table); @@ -2122,7 +2071,7 @@ static fx_result parse_table_header( new_table = fx_hashtable_create(); if (!new_table) { - free(key); + fx_string_unref(key); return FX_RESULT_ERR(NO_MEMORY); } @@ -2175,26 +2124,29 @@ static fx_result parse_array_header( } while (tok && tok->tok_type == TOK_DOT) { - const fx_value *child = fx_hashtable_get( - container, - &FX_VALUE_OBJECT(key)); + const fx_value *child + = fx_hashtable_get(container, &FX_VALUE_OBJECT(key)); fx_object *sub_dict = NULL; fx_value_get_object(child, &sub_dict); - if (!sub_dict) { + enum object_flags flags = ctx_get_object_flags(ctx, (sub_dict)); + if (flags & OBJECT_KV_END_DEFINED) { + return FX_RESULT_ERR(BAD_FORMAT); + } + + if (!child) { sub_dict = (fx_hashtable_create()); fx_hashtable_put( container, &FX_VALUE_OBJECT(key), &FX_VALUE_OBJECT(sub_dict)); fx_hashtable_unref(sub_dict); - } else if (fx_object_is_type(sub_dict, FX_TYPE_ARRAY)) { -#if 0 - sub_dict = fx_array_at( + } else if (fx_value_is_type(child, FX_TYPE_ARRAY)) { + child = fx_array_get_ref( sub_dict, - fx_array_size(sub_dict) - 1); -#endif - } else if (!fx_object_is_type(sub_dict, FX_TYPE_HASHTABLE)) { + fx_array_get_size(sub_dict) - 1); + sub_dict = child->v_object; + } else if (!fx_value_is_type(child, FX_TYPE_HASHTABLE)) { return FX_RESULT_ERR(BAD_FORMAT); } @@ -2219,9 +2171,12 @@ static fx_result parse_array_header( return FX_RESULT_ERR(BAD_FORMAT); } - const fx_value *child = fx_hashtable_get( - container, - &FX_VALUE_OBJECT(key)); + const fx_value *child + = fx_hashtable_get(container, &FX_VALUE_OBJECT(key)); + if (child && !fx_value_is_type(child, FX_TYPE_ARRAY)) { + return FX_RESULT_ERR(BAD_FORMAT); + } + fx_array *array = NULL; fx_value_get_object(child, &array); @@ -2234,11 +2189,11 @@ static fx_result parse_array_header( } else if (!fx_object_is_type(array, FX_TYPE_ARRAY)) { return FX_RESULT_ERR(BAD_FORMAT); } - free(key); + fx_string_unref(key); enum object_flags flags = ctx_get_object_flags(ctx, (array)); if (flags & OBJECT_KV_END_DEFINED) { - return FX_RESULT_ERR(NO_MEMORY); + return FX_RESULT_ERR(BAD_FORMAT); } fx_hashtable *new_table = fx_hashtable_create(); @@ -2246,9 +2201,7 @@ static fx_result parse_array_header( return FX_RESULT_ERR(NO_MEMORY); } -#if 0 - fx_array_append(array, FX_RV(new_table)); -#endif + fx_array_push_back(array, FX_VALUE_OBJECT(new_table)); advance_token(ctx); *new_container = new_table; @@ -2330,7 +2283,7 @@ static fx_result parse_root(struct ctx *ctx, fx_hashtable **out) static fx_result toml_deserialise( fx_serial_ctx *serial, fx_stream *src, - fx_object **dest, + fx_value *dest, enum fx_serial_flags flags) { struct ctx ctx = {0}; @@ -2351,7 +2304,7 @@ static fx_result toml_deserialise( } if (ctx.ctx_flags & CTX_EOF) { - *dest = (fx_hashtable_create()); + *dest = FX_VALUE_OBJECT(fx_hashtable_create()); return FX_RESULT_SUCCESS; } @@ -2361,7 +2314,7 @@ static fx_result toml_deserialise( return fx_result_propagate(ctx.ctx_result); } - *dest = (data); + *dest = FX_VALUE_OBJECT(data); #if 0 ctx.ctx_flags = CTX_ENABLE_NUMBERS | CTX_ENABLE_TIMESTAMPS | CTX_ENABLE_BOOLS;