From 44b97c0c13c3cb05a5fed70326285b45bc7b37a6 Mon Sep 17 00:00:00 2001 From: Claudius Holeksa Date: Mon, 26 Jun 2023 15:25:29 +0200 Subject: c++,codec: Added kelsimple array and struct decoding / encoding --- src/codec/simple.h | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 161 insertions(+), 5 deletions(-) (limited to 'src/codec/simple.h') diff --git a/src/codec/simple.h b/src/codec/simple.h index 1b6cf0d..ad66f66 100644 --- a/src/codec/simple.h +++ b/src/codec/simple.h @@ -1,6 +1,12 @@ #pragma once #include "data.h" +#include "stream_value.h" + +#include + +#include +#include namespace saw { namespace encode { @@ -15,7 +21,7 @@ public: data() = default; buffer& get_buffer(){ - return buffer; + return buffer_; } }; @@ -25,13 +31,152 @@ class kelsimple_encode { static_assert(always_false, "This schema type is not being handled by the kelsimple encoding."); }; -template +template struct kelsimple_encode, FromEnc> { static error_or encode(const data, FromEnc>& from, buffer& to){ - + auto eov = stream_value>::encode(from.get(), to); + return eov; + } +}; + +template +struct kelsimple_encode, FromEnc> { + template + static error_or encode_level(const data, FromEnc>& from, buffer& to, std::array& index){ + if constexpr (Dim == Level){ + return kelsimple_encode::encode(from.at(index), to); + } else { + const std::size_t dim_size = from.get_dim_size(Level); + for(index[Level] = 0; (index.at(Level) < dim_size); ++index[Level]){ + auto eov = encode_level(from, to, index); + if(eov.is_error()){ + return eov; + } + } + } + return void_t{}; + } + + static error_or encode(const data, FromEnc>& from, buffer& to){ + { + for(uint64_t i = 0; i < Dim; ++i){ + auto eov = stream_value::encode(from.get_dim_size(i), to); + if(eov.is_error()){ + return eov; + } + } + } + { + std::array index; + std::fill(index.begin(), index.end(), 0); + + return encode_level<0>(from, to, index); + } + return void_t{}; + } +}; + +template +struct kelsimple_encode...>,FromEnc> { + template + static error_or encode_member(const data...>, FromEnc>& from, buffer& to){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Literal = parameter_key_pack_type::literal; + { + auto eov = kelsimple_encode::encode(from.template get(), to); + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = encode_member(from, to); + if(eov.is_error()){ + return eov; + } + } + return void_t{}; + } + + static error_or encode(const data...>, FromEnc>& from, buffer& to){ + return encode_member<0>(from, to); + } +}; + +template +class kelsimple_decode { + static_assert(always_false, "This schema type is not being handled by the kelsimple encoding."); +}; + +template +struct kelsimple_decode, FromEnc> { + static error_or decode(buffer& from, data, FromEnc>& to){ + typename native_data_type>::type val{}; + auto eov = stream_value>::decode(val, from); + if (eov.is_value()) { + to.set(val); + } + return eov; + } + +}; +template +struct kelsimple_decode, FromEnc> { + template + static error_or decode_level(buffer& from, data, FromEnc>& to, std::array& index){ + if constexpr (Level == Dim){ + return kelsimple_decode::decode(from, to.at(index)); + }else{ + const std::size_t dim_size = to.get_dim_size(Level); + for(index[Level] = 0; index[Level] < dim_size; ++index[Level]){ + auto eov = decode_level(from, to, index); + if(eov.is_error()){ + return eov; + } + } + } + return void_t{}; + } + + static error_or decode(buffer& from, data, FromEnc>& to){ + { + std::array dims{}; + for(std::size_t i = 0; i < Dim; ++i){ + uint64_t val{}; + auto eov = stream_value::decode(val, from); + if(eov.is_error()){ + return eov; + } + dims.at(i) = static_cast(val); + } + to = data,FromEnc>{dims}; + } + { + std::array index{}; + return decode_level<0>(from, to, index); + } + return void_t{}; + } +}; +template +struct kelsimple_decode...>,FromEnc> { + template + static error_or decode_member(buffer& from, data...>, FromEnc>& to){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Literal = parameter_key_pack_type::literal; + { + auto eov = kelsimple_decode::decode(from, to.template get()); + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = decode_member(from, to); + if(eov.is_error()){ + return eov; + } + } return void_t{}; + } + static error_or decode(buffer& from, data...>, FromEnc>& to){ + return decode_member<0>(from, to); + } + }; } @@ -54,9 +199,20 @@ public: error_or encode(const data& from_enc, data& to_enc){ buffer_view buff_v{to_enc.get_buffer()}; - auto eov = kelsimple_encode::encode(from_env, buff_v); + auto eov = impl::kelsimple_encode::encode(from_enc, buff_v); - return void_t{}; + to_enc.get_buffer().write_advance(buff_v.write_offset()); + + return eov; + } + + template + error_or decode(data& from_dec, data& to){ + buffer_view buff_v{from_dec.get_buffer()}; + + auto eov = impl::kelsimple_decode::decode(buff_v, to); + + return eov; } }; } -- cgit v1.2.3