From e2b2f8b9a395a235e26e4b449b3498a2c0410f8f Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Thu, 29 Jun 2023 10:48:32 +0200 Subject: c++,codec-json: Added Struct decoding --- src/codec-json/json.tmpl.h | 99 +++++++++++++++++++++++++++++++++++++++++++++- tests/codec-json.cpp | 5 +-- 2 files changed, 100 insertions(+), 4 deletions(-) diff --git a/src/codec-json/json.tmpl.h b/src/codec-json/json.tmpl.h index 8fb01a9..6cf7189 100644 --- a/src/codec-json/json.tmpl.h +++ b/src/codec-json/json.tmpl.h @@ -461,9 +461,106 @@ struct json_decode { template struct json_decode...>, RootSchema, ToDecode> { + template + static error_or decode_field_search(buffer_view& buff, data...>, ToDecode>& to, std::array& fields, const data& search_name){ + if constexpr ( i < sizeof...(T)){ + using Type = typename parameter_pack_type::type; + constexpr static string_literal Literal = parameter_key_pack_type::literal; + if(search_name == Literal.view()){ + if(fields[i]){ + // TODO Change to this + // return make_error(); + return make_error(); + } + fields[i] = true; + auto eov = json_decode::decode(buff, to.template get()); + if(eov.is_error()){ + return eov; + } + }else { + decode_field_search(buff, to, fields, search_name); + } + }else { + return make_error(); + } + return void_t{}; + } + + static error_or decode_fields(buffer_view& buff, data...>, ToDecode>& to, std::array& fields){ + for(;;){ + data name; + auto eov = json_decode::decode(buff, name); + if(eov.is_error()){ + return eov; + } + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + if(buff.read() != ':'){ + return make_error(); + } + buff.read_advance(1); + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + { + auto eov = decode_field_search<0>(buff, to, fields, name); + if(eov.is_error()){ + return eov; + } + } + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + if(buff.read() == ','){ + buff.read_advance(1); + }else if(buff.read() == '}'){ + // If not all fields are set, the dataset is incomplete + for(auto& iter : fields){ + if(!iter){ + return make_error(); + } + } + buff.read_advance(1); + return void_t{}; + }else{ + return make_error(); + } + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + } + return void_t{}; + } + static error_or decode(buffer_view& buff, data...>, ToDecode>& to){ + std::array found_fields; + std::fill(found_fields.begin(), found_fields.end(), false); + + assert(buff.read() == '{'); + buff.read_advance(1); + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + if(buff.read() == '}'){ + if(sizeof...(T) > 0){ + return make_error(); + } + buff.read_advance(1); + return void_t{}; + } - return make_error(); + auto eov = decode_fields(buff, to, found_fields); + if(eov.is_error()){ + return eov; + } + + return void_t{}; } }; diff --git a/tests/codec-json.cpp b/tests/codec-json.cpp index 5b4700f..926f550 100644 --- a/tests/codec-json.cpp +++ b/tests/codec-json.cpp @@ -285,7 +285,7 @@ SAW_TEST("Three Dim Array write and read"){ } -SAW_TEST("Struct write"){ +SAW_TEST("Struct read and write"){ using namespace saw; data native; data json; @@ -302,13 +302,12 @@ SAW_TEST("Struct write"){ std::string enc_val = convert_to_string(json.get_buffer()); SAW_EXPECT(enc_val == str_v, std::string{"Struct not encoded correctly. Encoded: "} + enc_val + std::string{" Expected: "} + std::string{str_v}); -/* + native = {}; eov = json_codec.decode(json, native); SAW_EXPECT(eov.is_value(), "Decoding error"); SAW_EXPECT(native.get<"foo">().get() == 5, "Invalid value for foo"); SAW_EXPECT(native.get<"bar">() == "baz", "Invalid value for bar"); -*/ } SAW_TEST("Int8 read"){ -- cgit v1.2.3