summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudius Holeksa <mail@keldu.de>2023-06-26 18:19:15 +0200
committerClaudius Holeksa <mail@keldu.de>2023-06-26 18:19:15 +0200
commit7668b8aceb42b5a46e1f9ca36d16dbfabe291748 (patch)
tree7b5a72e74c1097dca0f042e0246ae0e06d164cc2
parent44b97c0c13c3cb05a5fed70326285b45bc7b37a6 (diff)
c++,codec: Introduced Tuple and String as KelSimple Encoding
-rw-r--r--src/codec/data.h11
-rw-r--r--src/codec/simple.h94
-rw-r--r--tests/codec.cpp60
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");
+}
}