From 7668b8aceb42b5a46e1f9ca36d16dbfabe291748 Mon Sep 17 00:00:00 2001 From: Claudius Holeksa Date: Mon, 26 Jun 2023 18:19:15 +0200 Subject: c++,codec: Introduced Tuple and String as KelSimple Encoding --- src/codec/data.h | 11 +++++++ src/codec/simple.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 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 - #include #include @@ -99,6 +97,52 @@ struct kelsimple_encode...>,FromEnc> { } }; +template +struct kelsimple_encode, FromEnc> { + template + static error_or encode_member(const data, FromEnc>& from, buffer& to){ + using Type = typename parameter_pack_type::type; + { + 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 +struct kelsimple_encode { + static error_or encode(const data& from, buffer& to){ + const auto str_size = from.size(); + typename native_data_type::type str_len = static_cast(str_size); + { + auto eov = stream_value::encode(str_len, to); + if(eov.is_error()){ + return eov; + } + } + + for(std::size_t i = 0; i < str_size; ++i){ + auto eov = stream_value::encode(from.at(i), to); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template class kelsimple_decode { static_assert(always_false, "This schema type is not being handled by the kelsimple encoding."); @@ -178,6 +222,52 @@ struct kelsimple_decode...>,FromEnc> { } }; +template +struct kelsimple_decode,FromEnc> { + template + static error_or decode_member(buffer& from, data, FromEnc>& to){ + using Type = typename parameter_pack_type::type; + { + 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); + } + +}; +template +struct kelsimple_decode { + static error_or decode(buffer& from, data& to){ + { + uint64_t val{}; + auto eov = stream_value::decode(val, from); + if(eov.is_error()){ + return eov; + } + to = data{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::decode(val, from); + if(eov.is_error()){ + return eov; + } + to.set_at(i, val); + } + return void_t{}; + } +}; + } template 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 #include +#include + namespace { namespace schema { using namespace saw::schema; @@ -15,6 +17,11 @@ using TestStruct = Struct< Member, Member >; + +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 native; + data 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 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 native; + data simple; + + std::string str = "FooBananaJoe"; + + native.set(str); + + codec 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"); +} } -- cgit v1.2.3