diff options
-rw-r--r-- | src/codec-json/json.tmpl.h | 59 | ||||
-rw-r--r-- | src/codec/data.h | 8 | ||||
-rw-r--r-- | tests/codec-json.cpp | 25 |
3 files changed, 70 insertions, 22 deletions
diff --git a/src/codec-json/json.tmpl.h b/src/codec-json/json.tmpl.h index 0d1c7f0..f5788e7 100644 --- a/src/codec-json/json.tmpl.h +++ b/src/codec-json/json.tmpl.h @@ -120,36 +120,51 @@ struct json_encode<schema::Tuple<T...>, RootSchema, FromEncode> { } }; -template<typename T, typename RootSchema, typename FromEncode> -struct json_encode<schema::Array<T>, RootSchema, FromEncode> { - static error_or<void> encode(const data<schema::Array<T>, FromEncode>& from, buffer& to) { - { - auto err = to.push('['); - if(!err.template is_type<err::no_error>()){ - return err; +template<typename T, size_t D, typename RootSchema, typename FromEncode> +struct json_encode<schema::Array<T,D>, RootSchema, FromEncode> { + template<size_t Level> + static error_or<void> encode_level(const data<schema::Array<T,D>, FromEncode>& from, buffer& to, std::array<std::size_t, D>& index){ + if constexpr (Level == D){ + auto eov = json_encode<T, RootSchema, FromEncode>::encode(from.at(index), to); + if(eov.is_error()){ + return eov; } - } - for(std::size_t i = 0; i < from.size(); ++i){ - if(i > 0){ - auto eov_ele = to.push(','); - if(!eov_ele.template is_type<err::no_error>()){ - return eov_ele; + } else { + { + auto err = to.push('['); + if(!err.template is_type<err::no_error>()){ + return err; } } - auto eov = json_encode<T, RootSchema, FromEncode>::encode(from.at(i), to); - if(eov.is_error()){ - return eov; + for(std::size_t i = 0; i < from.get_dim_size(Level); ++i){ + if( i > 0 ){ + auto err = to.push(','); + if(!err.template is_type<err::no_error>()){ + return err; + } + } + { + index[Level] = i; + auto eov = encode_level<Level+1>(from, to, index); + if(eov.is_error()){ + return eov; + } + } } - } - { - auto err = to.push(']'); - if(!err.template is_type<err::no_error>()){ - return err; + { + auto err = to.push(']'); + if(!err.template is_type<err::no_error>()){ + return err; + } } } - return void_t{}; } + + static error_or<void> encode(const data<schema::Array<T,D>, FromEncode>& from, buffer& to) { + std::array<std::size_t, D> index; + return encode_level<0>(from, to, index); + } }; template<typename... T, string_literal... Key, typename RootSchema, typename FromEncode> diff --git a/src/codec/data.h b/src/codec/data.h index 7ed672b..5cb1267 100644 --- a/src/codec/data.h +++ b/src/codec/data.h @@ -207,6 +207,14 @@ class data<schema::Array<T,Dim>, encode::Native> { value_.resize(get_full_size()); } + data<T, encode::Native>& at(const std::array<std::size_t, Dim>& ind){ + return value_.at(this->get_index(ind)); + } + + const data<T, encode::Native>& at(const std::array<std::size_t, Dim>& ind) const { + return value_.at(this->get_index(ind)); + } + template<std::integral... Dims> data<T, encode::Native>& at(Dims... i){ return value_.at(this->get_index({i...})); diff --git a/tests/codec-json.cpp b/tests/codec-json.cpp index 1b6c5d2..1c77f46 100644 --- a/tests/codec-json.cpp +++ b/tests/codec-json.cpp @@ -16,6 +16,10 @@ using TestArray = Array< String, 1 >; +using TestMultiArray = Array< + String, 3 +>; + using TestStruct = Struct< Member<Int32, "foo">, Member<String, "bar"> @@ -104,6 +108,27 @@ SAW_TEST("Array write"){ SAW_EXPECT(enc_val == str_v, std::string{"Array not encoded correctly. Encoded: "} + enc_val + std::string{" Expected: "} + std::string{str_v}); } +SAW_TEST("Three Dim Array write"){ + using namespace saw; + data<schema::TestMultiArray, encode::Native> native{2,1,2}; + data<schema::TestMultiArray, encode::Json> json; + + native.at(0,0,0).set("multi"); + native.at(0,0,1).set("baz"); + native.at(1,0,0).set("foo"); + native.at(1,0,1).set("bar"); + + codec<schema::TestMultiArray, encode::Json> json_codec; + + error_or<void> eov = json_codec.encode(native, json); + SAW_EXPECT(eov.is_value(), "Encoding error"); + + std::string_view str_v = "[[[\"multi\",\"baz\"]],[[\"foo\",\"bar\"]]]"; + std::string enc_val = convert_to_string(json.get_buffer()); + + SAW_EXPECT(enc_val == str_v, std::string{"Array not encoded correctly. Encoded: "} + enc_val + std::string{" Expected: "} + std::string{str_v}); +} + SAW_TEST("Struct write"){ using namespace saw; data<schema::TestStruct, encode::Native> native; |