From 056ab6893ca18c33c7fb01d24498f9149fba4e8a Mon Sep 17 00:00:00 2001 From: Claudius Holeksa Date: Tue, 20 Jun 2023 17:00:38 +0200 Subject: c++, codec-json: Minor progress on arrays for json decoding --- src/codec-json/json.h | 16 ++++++ src/codec-json/json.tmpl.h | 134 +++++++++++++++++++++++++++------------------ tests/codec-json.cpp | 23 +++++++- 3 files changed, 118 insertions(+), 55 deletions(-) diff --git a/src/codec-json/json.h b/src/codec-json/json.h index 58b64aa..1fe6bb5 100644 --- a/src/codec-json/json.h +++ b/src/codec-json/json.h @@ -20,6 +20,16 @@ public: data(std::size_t ring_size_):buffer_{ring_size_}{} + data(const std::string_view& view__): + buffer_{view__.size()} + { + auto ptr = reinterpret_cast(view__.data()); + if(!ptr){ + return; + } + buffer_.push(*ptr, view__.size()); + } + buffer& get_buffer(){ return buffer_; } @@ -93,6 +103,12 @@ public: error_or decode(data& from_decode, data& to_decode){ buffer_view buff_v{from_decode.get_buffer()}; + auto eov = impl::json_decode::decode(buff_v, to_decode); + if(eov.is_error()){ + return std::move(eov.get_error()); + } + from_decode.get_buffer().read_advance(buff_v.read_offset()); + return void_t {}; } }; diff --git a/src/codec-json/json.tmpl.h b/src/codec-json/json.tmpl.h index b8cd7aa..0f6c59f 100644 --- a/src/codec-json/json.tmpl.h +++ b/src/codec-json/json.tmpl.h @@ -10,7 +10,7 @@ class json_encode { }; template -struct json_encode, RootSchema, FromEncode> { +struct json_encode, RootSchema, FromEncode> { static error_or encode(const data, FromEncode>& from, buffer& to) { auto val = from.get(); std::array data; @@ -38,58 +38,6 @@ struct json_encode, RootSchema, FromEncode> { return void_t{}; } - - static error_or decode(buffer_view& buff, data, FromEncode>& to){ - assert((buff.read() >= '0' && buff.read() <= '9') || - buff.read() == '+' || buff.read() == '-'); - - std::size_t offset = 0; - - if(buff.read() == '-'){ - ++offset; - }else if(buff.read() == '+'){ - return make_error(); - } - if (offset >= buff.read_composite_length()) { - return make_error(); - } - if(buff.read(offset) >= '1' && buff.read(offset) <= '9'){ - ++offset; - - if(offset >= buff.read_composite_length()){ - return make_error(); - } - - while(1){ - if (buff.read(offset) >= '0' && buff.read(offset) <= '9'){ - ++offset; - - if(offset >= buff.read_composite_length()){ - return make_error(); - } - continue; - } - break; - } - }else if (buff.read(offset) == '0' ){ - ++offset; - }else{ - return make_error(); - } - - { - std::string_view num_view{reinterpret_cast(&buff.read()), offset}; - typename native_data_type>::type result; - auto fc_result = std::from_chars(num_view.data(), num_view.data() + num_view.size(), result); - if(fc_result.ec != std::errc{}){ - return make_error(); - } - - to.set(result); - } - - return void_t{}; - } }; template @@ -369,6 +317,86 @@ struct json_encode...>, RootSchema, FromEnco template struct json_decode; +template +struct json_decode, RootSchema, ToDecode> { + static error_or decode(buffer_view& buff, data, ToDecode>& to){ + assert((buff.read() >= '0' && buff.read() <= '9') || + buff.read() == '+' || buff.read() == '-'); + + std::size_t offset = 0; + + if(buff.read() == '-'){ + ++offset; + }else if(buff.read() == '+'){ + return make_error(); + } + if (offset >= buff.read_composite_length()) { + return make_error(); + } + if(buff.read(offset) >= '1' && buff.read(offset) <= '9'){ + ++offset; + + if(offset >= buff.read_composite_length()){ + return make_error(); + } + while(1){ + if (buff.read(offset) >= '0' && buff.read(offset) <= '9'){ + ++offset; + + if(offset >= buff.read_composite_length()){ + break; + } + continue; + } + break; + } + }else if (buff.read(offset) == '0' ){ + ++offset; + }else{ + return make_error(); + } + + { + std::string_view num_view{reinterpret_cast(&buff.read()), offset}; + typename native_data_type>::type result; + auto fc_result = std::from_chars(num_view.data(), num_view.data() + num_view.size(), result); + if(fc_result.ec != std::errc{}){ + return make_error(); + } + + to.set(result); + } + buff.read_advance(offset); + + return void_t{}; + } +}; + +template +struct json_decode, RootSchema, ToDecode> { + template + static error_or decode_level(buffer_view& buff, data, ToDecode>& to, std::array& index){ + if constexpr (Level == D) { + auto eov = json_decode::decode(buff, to.at(index)); + if(eov.is_error()){ + return eov; + } + } else { + assert(buff.read() == '['); + buff.read_advance(1); + if( buff.read_composite_length() == 0 ){ + return make_error(); + } + + } + return void_t{}; + } + + static error_or decode(buffer_view& buff, data, ToDecode>& to){ + std::array index; + return decode_level<0>(buff, to, index); + } +}; } } diff --git a/tests/codec-json.cpp b/tests/codec-json.cpp index 030b1e4..fec82b0 100644 --- a/tests/codec-json.cpp +++ b/tests/codec-json.cpp @@ -292,12 +292,13 @@ SAW_TEST("Struct write"){ SAW_TEST("Int8 read"){ using namespace saw; data native_int; - data json_int; + data json_int{"43"}; codec json_codec; error_or eov = json_codec.decode(json_int, native_int); - SAW_EXPECT(eov.is_value(), "Encoding error"); + std::string enc_val = convert_to_string(json_int.get_buffer()); + SAW_EXPECT(eov.is_value(), std::string{"Encoding error: "} + enc_val); /** * Currently doing this manually. Technically I should convert to std::string for tests @@ -305,4 +306,22 @@ SAW_TEST("Int8 read"){ typename native_data_type::type dec_val = 43; SAW_EXPECT( dec_val == native_int.get(), std::string{"Value is not being encoded correctly. Encoded: "} + std::to_string(static_cast(native_int.get()))); } + +SAW_TEST("Int64 read"){ + using namespace saw; + data native_int; + data json_int{"-453"}; + + codec json_codec; + + error_or eov = json_codec.decode(json_int, native_int); + std::string enc_val = convert_to_string(json_int.get_buffer()); + SAW_EXPECT(eov.is_value(), std::string{"Encoding error: "} + enc_val); + + /** + * Currently doing this manually. Technically I should convert to std::string for tests + */ + typename native_data_type::type dec_val = -453; + SAW_EXPECT( dec_val == native_int.get(), std::string{"Value is not being encoded correctly. Encoded: "} + std::to_string(static_cast(native_int.get()))); +} } -- cgit v1.2.3