diff options
author | Claudius Holeksa <mail@keldu.de> | 2023-06-26 18:19:15 +0200 |
---|---|---|
committer | Claudius Holeksa <mail@keldu.de> | 2023-06-26 18:19:15 +0200 |
commit | 7668b8aceb42b5a46e1f9ca36d16dbfabe291748 (patch) | |
tree | 7b5a72e74c1097dca0f042e0246ae0e06d164cc2 | |
parent | 44b97c0c13c3cb05a5fed70326285b45bc7b37a6 (diff) |
c++,codec: Introduced Tuple and String as KelSimple Encoding
-rw-r--r-- | src/codec/data.h | 11 | ||||
-rw-r--r-- | src/codec/simple.h | 94 | ||||
-rw-r--r-- | tests/codec.cpp | 60 |
3 files changed, 163 insertions, 2 deletions
diff --git a/src/codec/data.h b/src/codec/data.h index a43fdd8..9eb2bfc 100644 --- a/src/codec/data.h +++ b/src/codec/data.h @@ -244,6 +244,9 @@ public: SAW_DEFAULT_MOVE(data); data(std::string value__):value_{std::move(value__)}{} + data(std::size_t size_){ + value_.resize(size_); + } std::size_t size() const { return value_.size(); @@ -253,6 +256,14 @@ public: value_ = std::move(str); } + char& at(size_t i) { + return value_.at(i); + } + + const char& at(size_t i) const { + return value_.at(i); + } + char get_at(size_t i) const{ return value_.at(i); } diff --git a/src/codec/simple.h b/src/codec/simple.h index ad66f66..8712c6d 100644 --- a/src/codec/simple.h +++ b/src/codec/simple.h @@ -3,8 +3,6 @@ #include "data.h" #include "stream_value.h" -#include <iostream> - #include <forstio/core/buffer.h> #include <forstio/core/error.h> @@ -99,6 +97,52 @@ struct kelsimple_encode<schema::Struct<schema::Member<T,Lits>...>,FromEnc> { } }; +template<typename... T, typename FromEnc> +struct kelsimple_encode<schema::Tuple<T...>, FromEnc> { + template<std::size_t i> + static error_or<void> encode_member(const data<schema::Tuple<T...>, FromEnc>& from, buffer& to){ + using Type = typename parameter_pack_type<i,T...>::type; + { + auto eov = kelsimple_encode<Type, FromEnc>::encode(from.template get<i>(), to); + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = encode_member<i+1>(from, to); + if(eov.is_error()){ + return eov; + } + } + return void_t{}; + } + + static error_or<void> encode(const data<schema::Tuple<T...>, FromEnc>& from, buffer& to){ + return encode_member<0>(from, to); + } +}; + +template<typename FromEnc> +struct kelsimple_encode<schema::String, FromEnc> { + static error_or<void> encode(const data<schema::String, FromEnc>& from, buffer& to){ + const auto str_size = from.size(); + typename native_data_type<schema::UInt64>::type str_len = static_cast<uint64_t>(str_size); + { + auto eov = stream_value<schema::UInt64>::encode(str_len, to); + if(eov.is_error()){ + return eov; + } + } + + for(std::size_t i = 0; i < str_size; ++i){ + auto eov = stream_value<schema::Int8>::encode(from.at(i), to); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template<typename Schema, typename FromEnc> class kelsimple_decode { static_assert(always_false<Schema, FromEnc>, "This schema type is not being handled by the kelsimple encoding."); @@ -178,6 +222,52 @@ struct kelsimple_decode<schema::Struct<schema::Member<T,Lits>...>,FromEnc> { } }; +template<typename... T, typename FromEnc> +struct kelsimple_decode<schema::Tuple<T...>,FromEnc> { + template<std::size_t i> + static error_or<void> decode_member(buffer& from, data<schema::Tuple<T...>, FromEnc>& to){ + using Type = typename parameter_pack_type<i,T...>::type; + { + auto eov = kelsimple_decode<Type, FromEnc>::decode(from, to.template get<i>()); + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = decode_member<i+1>(from, to); + if(eov.is_error()){ + return eov; + } + } + return void_t{}; + + } + static error_or<void> decode(buffer& from, data<schema::Tuple<T...>, FromEnc>& to){ + return decode_member<0>(from, to); + } + +}; +template<typename FromEnc> +struct kelsimple_decode<schema::String, FromEnc> { + static error_or<void> decode(buffer& from, data<schema::String, FromEnc>& to){ + { + uint64_t val{}; + auto eov = stream_value<schema::UInt64>::decode(val, from); + if(eov.is_error()){ + return eov; + } + to = data<schema::String,FromEnc>{val}; + } + const std::size_t str_size = to.size(); + for(std::size_t i = 0; i < str_size; ++i){ + int8_t val{}; + auto eov = stream_value<schema::Int8>::decode(val, from); + if(eov.is_error()){ + return eov; + } + to.set_at(i, val); + } + return void_t{}; + } +}; + } template<typename Schema> diff --git a/tests/codec.cpp b/tests/codec.cpp index 5186df3..442ae57 100644 --- a/tests/codec.cpp +++ b/tests/codec.cpp @@ -2,6 +2,8 @@ #include <forstio/codec/data.h> #include <forstio/codec/simple.h> +#include <iostream> + namespace { namespace schema { using namespace saw::schema; @@ -15,6 +17,11 @@ using TestStruct = Struct< Member<TwoDimArray, "two_dim_array">, Member<UInt64, "number"> >; + +using TestTuple = Tuple< + TwoDimArray, + UInt64 +>; } SAW_TEST("One Dimensional Array") { using namespace saw; @@ -189,4 +196,57 @@ SAW_TEST("KelSimple Struct write and read back"){ SAW_EXPECT(dec_tda.at(0,1).get() == 3, "Incorrect Decoding in array 0,1"); SAW_EXPECT(native.template get<"number">().get() == 410, "Incorrect Decoding in number"); } +SAW_TEST("KelSimple Tuple write and read back"){ + using namespace saw; + + data<schema::TestTuple,encode::Native> native; + data<schema::TestTuple,encode::KelSimple> simple; + + auto& tda = native.template get<0>(); + tda = {1,2}; + + tda.at(0,0).set(5); + tda.at(0,1).set(3); + native.template get<1>().set(410); + + codec<schema::TestTuple, encode::KelSimple> codec; + + auto eov = codec.encode(native, simple); + SAW_EXPECT(eov.is_value(), "Encoding error"); + + // Reset values + native = {}; + + eov = codec.decode(simple, native); + SAW_EXPECT(eov.is_value(), "Decoding error"); + + auto& dec_tda = native.template get<0>(); + + SAW_EXPECT(dec_tda.at(0,0).get() == 5, "Incorrect Decoding in array 0,0"); + SAW_EXPECT(dec_tda.at(0,1).get() == 3, "Incorrect Decoding in array 0,1"); + SAW_EXPECT(native.template get<1>().get() == 410, "Incorrect Decoding in number"); +} +SAW_TEST("KelSimple String write and read back"){ + using namespace saw; + + data<schema::String,encode::Native> native; + data<schema::String,encode::KelSimple> simple; + + std::string str = "FooBananaJoe"; + + native.set(str); + + codec<schema::String, encode::KelSimple> codec; + + auto eov = codec.encode(native, simple); + SAW_EXPECT(eov.is_value(), "Encoding error"); + + // Reset values + native = {}; + + eov = codec.decode(simple, native); + SAW_EXPECT(eov.is_value(), "Decoding error"); + + SAW_EXPECT(native == str, "String should've been decoded back correctly"); +} } |