From a863f9af9fff0ecb276c6769149d9672961b7533 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Mon, 4 Dec 2023 17:01:04 +0100 Subject: codec: Moving structure around --- modules/codec/SConscript | 38 ---- modules/codec/SConstruct | 2 +- modules/codec/args.h | 123 ----------- modules/codec/c++/SConscript | 38 ++++ modules/codec/c++/args.h | 123 +++++++++++ modules/codec/c++/csv.h | 25 +++ modules/codec/c++/data.h | 370 +++++++++++++++++++++++++++++++++ modules/codec/c++/forst.h | 32 +++ modules/codec/c++/forst.tmpl.h | 7 + modules/codec/c++/interface.h | 103 ++++++++++ modules/codec/c++/rpc.h | 26 +++ modules/codec/c++/schema.h | 109 ++++++++++ modules/codec/c++/schema_hash.h | 105 ++++++++++ modules/codec/c++/schema_stringify.h | 118 +++++++++++ modules/codec/c++/simple.h | 389 +++++++++++++++++++++++++++++++++++ modules/codec/c++/stream_value.h | 64 ++++++ modules/codec/csv.h | 25 --- modules/codec/data.h | 370 --------------------------------- modules/codec/forst.h | 32 --- modules/codec/forst.tmpl.h | 7 - modules/codec/interface.h | 103 ---------- modules/codec/rpc.h | 26 --- modules/codec/schema.h | 109 ---------- modules/codec/schema_hash.h | 105 ---------- modules/codec/schema_stringify.h | 118 ----------- modules/codec/simple.h | 389 ----------------------------------- modules/codec/stream_value.h | 64 ------ modules/codec/tests/SConscript | 29 +++ 28 files changed, 1539 insertions(+), 1510 deletions(-) delete mode 100644 modules/codec/SConscript delete mode 100644 modules/codec/args.h create mode 100644 modules/codec/c++/SConscript create mode 100644 modules/codec/c++/args.h create mode 100644 modules/codec/c++/csv.h create mode 100644 modules/codec/c++/data.h create mode 100644 modules/codec/c++/forst.h create mode 100644 modules/codec/c++/forst.tmpl.h create mode 100644 modules/codec/c++/interface.h create mode 100644 modules/codec/c++/rpc.h create mode 100644 modules/codec/c++/schema.h create mode 100644 modules/codec/c++/schema_hash.h create mode 100644 modules/codec/c++/schema_stringify.h create mode 100644 modules/codec/c++/simple.h create mode 100644 modules/codec/c++/stream_value.h delete mode 100644 modules/codec/csv.h delete mode 100644 modules/codec/data.h delete mode 100644 modules/codec/forst.h delete mode 100644 modules/codec/forst.tmpl.h delete mode 100644 modules/codec/interface.h delete mode 100644 modules/codec/rpc.h delete mode 100644 modules/codec/schema.h delete mode 100644 modules/codec/schema_hash.h delete mode 100644 modules/codec/schema_stringify.h delete mode 100644 modules/codec/simple.h delete mode 100644 modules/codec/stream_value.h create mode 100644 modules/codec/tests/SConscript (limited to 'modules') diff --git a/modules/codec/SConscript b/modules/codec/SConscript deleted file mode 100644 index c038d42..0000000 --- a/modules/codec/SConscript +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/false - -import os -import os.path -import glob - - -Import('env') - -dir_path = Dir('.').abspath - -# Environment for base library -codec_env = env.Clone(); - -codec_env.sources = sorted(glob.glob(dir_path + "/*.cpp")) -codec_env.headers = sorted(glob.glob(dir_path + "/*.h")) - -env.sources += codec_env.sources; -env.headers += codec_env.headers; - -## Shared lib -objects_shared = [] -codec_env.add_source_files(objects_shared, codec_env.sources, shared=True); -codec_env.library_shared = codec_env.SharedLibrary('#build/forstio-codec', [objects_shared]); - -## Static lib -objects_static = [] -codec_env.add_source_files(objects_static, codec_env.sources, shared=False); -codec_env.library_static = codec_env.StaticLibrary('#build/forstio-codec', [objects_static]); - -# Set Alias -env.Alias('library_codec', [codec_env.library_shared, codec_env.library_static]); - -env.targets += ['library_codec']; - -# Install -env.Install('$prefix/lib/', [codec_env.library_shared, codec_env.library_static]); -env.Install('$prefix/include/forstio/codec/', [codec_env.headers]); diff --git a/modules/codec/SConstruct b/modules/codec/SConstruct index 0d7b7c6..def568e 100644 --- a/modules/codec/SConstruct +++ b/modules/codec/SConstruct @@ -57,7 +57,7 @@ env.headers = []; env.targets = []; Export('env') -SConscript('SConscript') +SConscript('c++/SConscript') env.Alias('cdb', env.cdb); env.Alias('all', [env.targets]); diff --git a/modules/codec/args.h b/modules/codec/args.h deleted file mode 100644 index 6bb75a2..0000000 --- a/modules/codec/args.h +++ /dev/null @@ -1,123 +0,0 @@ -#pragma once - -#include "schema.h" - -namespace saw { -namespace encode { -struct Args {}; -} - -namespace schema { -template -using Args = Struct< - Member, - Member, - Member ->; -} - -template -class data { - static_assert(always_false,"Not supported. Use the schema::Args alias or check how it's defined."); -}; - -template -class data...>, schema::Tuple>, encode::Args> { -private: - char** argv_; - int argc_; -public: - data(char** argv, int argc): - argv_{argv}, - argc_{argc} - {} - - size_t size() const { - if(argc_ < 0){ - return 0; - } - - static_assert(sizeof(int) <= sizeof(size_t), "size_t is smaller than int"); - - return static_cast(argc_); - } - - std::string_view arg_view(size_t i){ - if(i < size()){ - return std::string_view{argv_[i]}; - } - return ""; - } -}; - -namespace impl { -template -struct args_decode { - static_assert(always_false, "Not supported"); -}; - -template -struct args_decode...>,schema::Tuple>,ToDec> { - using Schema = schema::Args< - schema::Struct...>, - schema::Tuple - >; - - static error_or decode(data& from, data& to){ - if(from.size() == 0){ - return make_error(); - } - - to.get<"program">().set(std::string{from.arg_view(0)}); - std::size_t tuple_pos = 0; - for(size_t i = 1; i < from.size(); ++i){ - auto view = from.arg_view(i); - if(view.starts_with("--")){ - view.remove_prefix(std::min(2u, view.size())); - ++i; - - if( i >= from.size() ){ - return make_error(); - } - - auto value_view = from.arg_view(i); - - auto eov = decode_struct_member<0>(to.get<"args">(), view, value_view); - if(eov.is_error()){ - return eov; - } - } else { - auto eov = decode_tuple_member<0>(to.get<"positionals">(), view); - if(eov.is_error()){ - return eov; - } - ++tuple_pos; - } - } - - if(tuple_pos != sizeof...(Tup)){ - return make_error(); - } - - return void_t{}; - } -}; -} - -template -class codec { -public: - template - error_or decode(data& from, data& to){ - struct name_and_value { - std::string name; - std::string value; - }; - std::string program; - std::vector navs; - std::vector positionals; - - return void_t{}; - } -}; -} diff --git a/modules/codec/c++/SConscript b/modules/codec/c++/SConscript new file mode 100644 index 0000000..c038d42 --- /dev/null +++ b/modules/codec/c++/SConscript @@ -0,0 +1,38 @@ +#!/bin/false + +import os +import os.path +import glob + + +Import('env') + +dir_path = Dir('.').abspath + +# Environment for base library +codec_env = env.Clone(); + +codec_env.sources = sorted(glob.glob(dir_path + "/*.cpp")) +codec_env.headers = sorted(glob.glob(dir_path + "/*.h")) + +env.sources += codec_env.sources; +env.headers += codec_env.headers; + +## Shared lib +objects_shared = [] +codec_env.add_source_files(objects_shared, codec_env.sources, shared=True); +codec_env.library_shared = codec_env.SharedLibrary('#build/forstio-codec', [objects_shared]); + +## Static lib +objects_static = [] +codec_env.add_source_files(objects_static, codec_env.sources, shared=False); +codec_env.library_static = codec_env.StaticLibrary('#build/forstio-codec', [objects_static]); + +# Set Alias +env.Alias('library_codec', [codec_env.library_shared, codec_env.library_static]); + +env.targets += ['library_codec']; + +# Install +env.Install('$prefix/lib/', [codec_env.library_shared, codec_env.library_static]); +env.Install('$prefix/include/forstio/codec/', [codec_env.headers]); diff --git a/modules/codec/c++/args.h b/modules/codec/c++/args.h new file mode 100644 index 0000000..6bb75a2 --- /dev/null +++ b/modules/codec/c++/args.h @@ -0,0 +1,123 @@ +#pragma once + +#include "schema.h" + +namespace saw { +namespace encode { +struct Args {}; +} + +namespace schema { +template +using Args = Struct< + Member, + Member, + Member +>; +} + +template +class data { + static_assert(always_false,"Not supported. Use the schema::Args alias or check how it's defined."); +}; + +template +class data...>, schema::Tuple>, encode::Args> { +private: + char** argv_; + int argc_; +public: + data(char** argv, int argc): + argv_{argv}, + argc_{argc} + {} + + size_t size() const { + if(argc_ < 0){ + return 0; + } + + static_assert(sizeof(int) <= sizeof(size_t), "size_t is smaller than int"); + + return static_cast(argc_); + } + + std::string_view arg_view(size_t i){ + if(i < size()){ + return std::string_view{argv_[i]}; + } + return ""; + } +}; + +namespace impl { +template +struct args_decode { + static_assert(always_false, "Not supported"); +}; + +template +struct args_decode...>,schema::Tuple>,ToDec> { + using Schema = schema::Args< + schema::Struct...>, + schema::Tuple + >; + + static error_or decode(data& from, data& to){ + if(from.size() == 0){ + return make_error(); + } + + to.get<"program">().set(std::string{from.arg_view(0)}); + std::size_t tuple_pos = 0; + for(size_t i = 1; i < from.size(); ++i){ + auto view = from.arg_view(i); + if(view.starts_with("--")){ + view.remove_prefix(std::min(2u, view.size())); + ++i; + + if( i >= from.size() ){ + return make_error(); + } + + auto value_view = from.arg_view(i); + + auto eov = decode_struct_member<0>(to.get<"args">(), view, value_view); + if(eov.is_error()){ + return eov; + } + } else { + auto eov = decode_tuple_member<0>(to.get<"positionals">(), view); + if(eov.is_error()){ + return eov; + } + ++tuple_pos; + } + } + + if(tuple_pos != sizeof...(Tup)){ + return make_error(); + } + + return void_t{}; + } +}; +} + +template +class codec { +public: + template + error_or decode(data& from, data& to){ + struct name_and_value { + std::string name; + std::string value; + }; + std::string program; + std::vector navs; + std::vector positionals; + + return void_t{}; + } +}; +} diff --git a/modules/codec/c++/csv.h b/modules/codec/c++/csv.h new file mode 100644 index 0000000..67c2c1d --- /dev/null +++ b/modules/codec/c++/csv.h @@ -0,0 +1,25 @@ +#pragma once + +#include "data.h" + +namespace saw { +namespace encode { +struct Csv {}; +} + +template +class codec { +public: + template + static error_or encode(const data& from, data& to){ + + return make_error(); + } + + template + static error_or decode(data& from, data& to){ + + return make_error(); + } +}; +} diff --git a/modules/codec/c++/data.h b/modules/codec/c++/data.h new file mode 100644 index 0000000..237ef5a --- /dev/null +++ b/modules/codec/c++/data.h @@ -0,0 +1,370 @@ +#pragma once + +#include +#include + +#include + +#include +#include +#include +#include + +#include "schema.h" + +namespace saw { +namespace encode { +struct Native {}; +} +template +class codec; +/* + * Helper for the basic message container, so the class doesn't have to be + * specialized 10 times. + */ +template struct native_data_type; + +template <> +struct native_data_type> { + using type = int8_t; +}; + +template <> +struct native_data_type> { + using type = int16_t; +}; + +template <> +struct native_data_type> { + using type = int32_t; +}; + +template <> +struct native_data_type> { + using type = int64_t; +}; + +template <> +struct native_data_type> { + using type = uint8_t; +}; + +template <> +struct native_data_type> { + using type = uint16_t; +}; + +template <> +struct native_data_type> { + using type = uint32_t; +}; + +template <> +struct native_data_type> { + using type = uint64_t; +}; + +template <> +struct native_data_type> { + using type = float; +}; + +template <> +struct native_data_type> { + using type = double; +}; + +template +class data { +private: + static_assert(always_false, "Type not supported"); +}; + +template +class data...>, encode::Native> { +private: + std::variant...> value_; +public: + data() = default; + + SAW_DEFAULT_COPY(data); + SAW_DEFAULT_MOVE(data); + + template + void set(data::value, T...>::type, encode::Native> val){ + value_ = std::move(val); + } + + template + data::value, T...>::type, encode::Native>& init(){ + value_ = data::value, T...>::type, encode::Native>{}; + return get(); + } + + template + bool holds_alternative() const { + return (parameter_key_pack_index::value == value_.index()); + } + + template + data::value, T...>::type, encode::Native>& get(){ + return std::get::value>(value_); + } + + template + const data::value, T...>::type, encode::Native>& get() const{ + return std::get::value>(value_); + } +}; + +template +class data...>, encode::Native> { +private: + std::tuple...> value_; +public: + data() = default; + SAW_DEFAULT_COPY(data); + SAW_DEFAULT_MOVE(data); + + template + data< + typename parameter_pack_type< + parameter_key_pack_index< + literal, literals... + >::value + , T...>::type + , encode::Native>& get(){ + return std::get::value>(value_); + } + + template + const data< + typename parameter_pack_type< + parameter_key_pack_index< + literal, literals... + >::value + , T...>::type + , encode::Native>& get() const { + return std::get::value>(value_); + } + + constexpr size_t size() const { + return sizeof...(T); + } +}; + +template +class data, encode::Native> { +private: + std::tuple...> value_; +public: + data() = default; + SAW_DEFAULT_COPY(data); + SAW_DEFAULT_MOVE(data); + + template + data::type, encode::Native>& get(){ + return std::get(value_); + } + + template + const data::type, encode::Native>& get() const{ + return std::get(value_); + } + + constexpr size_t size() const { + return sizeof...(T); + } +}; + +template +class data, encode::Native> { + private: + std::array dims_; + std::vector> value_; + + std::size_t get_full_size() const { + std::size_t s = 1; + + for(std::size_t iter = 0; iter < Dim; ++iter){ + assert(dims_.at(iter) > 0); + s *= dims_.at(iter); + } + + return s; + } + public: + data() = default; + SAW_DEFAULT_COPY(data); + SAW_DEFAULT_MOVE(data); + + data(const std::array& i): + dims_{i}, + value_{} + { + value_.resize(get_full_size()); + } + + template + data(Dims... size_): + data{{size_...}} + { + static_assert(sizeof...(Dims)==Dim, "Argument size must be equal to the Dimension"); + } + + data& at(const std::array& ind){ + return value_.at(this->get_flat_index(ind)); + } + + const data& at(const std::array& ind) const { + return value_.at(this->get_flat_index(ind)); + } + + template + data& at(Dims... i){ + return value_.at(this->get_flat_index({i...})); + } + + template + const data& at(Dims... i) const { + return value_.at(this->get_flat_index({i...})); + } + + std::size_t get_dim_size(std::size_t i) const { + return dims_.at(i); + } + + size_t size() const { return value_.size();} + +private: + std::size_t get_flat_index(const std::array& i) const { + std::size_t s = 0; + + std::size_t stride = 1; + + for(std::size_t iter = 0; iter < Dim; ++iter){ + assert(i.at(iter) < dims_.at(iter)); + s += i.at(iter) * stride; + stride *= dims_.at(iter); + } + + return s; + } +}; + +template +class data, encode::Native> { +private: + //using inner_type = std::array, multiply_helper::value>; + //std::unique_ptr value_; + std::vector> value_; + +public: + data(){ + value_.resize(ct_multiply::value); + } + + data& at(const std::array& ind){ + return value_.at(this->get_flat_index(ind)); + } + + const data& at(const std::array& ind) const { + return value_.at(this->get_flat_index(ind)); + } + + template + data& at(Dims... i) { + return value_.at(this->get_flat_index({i...})); + } + + template + const data& at(Dims... i) const { + return value_.at(this->get_flat_index({i...})); + } + + template + std::size_t get_dim_size() const { + return parameter_pack_value::value; + } +private: + std::size_t get_flat_index(const std::array& i) const { + std::size_t s = 0; + + std::size_t stride = 1; + + constexpr static std::array dims_{D...}; + + for(std::size_t iter = 0; iter < sizeof...(D); ++iter){ + assert(i.at(iter) < dims_.at(iter)); + s += i.at(iter) * stride; + stride *= dims_.at(iter); + } + + return s; + } +}; + +template<> +class data { +private: + std::string value_; +public: + data() = default; + SAW_DEFAULT_COPY(data); + 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(); + } + + void set(std::string str){ + 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); + } + + void set_at(size_t i, char val){ + value_.at(i) = val; + } + + bool operator==(const std::string_view& val)const{ + return value_ == val; + } +}; + +template +class data, encode::Native> { +private: + typename native_data_type>::type value_; +public: + data():value_{{}}{}; + SAW_DEFAULT_COPY(data); + SAW_DEFAULT_MOVE(data); + + data(typename native_data_type>::type value__): + value_{std::move(value__)}{} + + void set(typename native_data_type>::type val){ + value_ = val; + } + + typename native_data_type>::type get() const {return value_;} +}; + + +} diff --git a/modules/codec/c++/forst.h b/modules/codec/c++/forst.h new file mode 100644 index 0000000..7e8fbf0 --- /dev/null +++ b/modules/codec/c++/forst.h @@ -0,0 +1,32 @@ +#pragma once + +#include "data.h" + +namespace saw { +namespace encode { +struct KelForst {}; +} +} + +#include "forst.tmpl.hpp" + +namespace saw { +class data { +private: + own buff_; +public: + data(own buff): + buff_{std::move(buff)} + {} +}; + +template +class data...>, encode::KelForst> { +private: + own buff_; +public: + data(own buff): + buff_{std::move(buff)} + {} +}; +} diff --git a/modules/codec/c++/forst.tmpl.h b/modules/codec/c++/forst.tmpl.h new file mode 100644 index 0000000..30d18ef --- /dev/null +++ b/modules/codec/c++/forst.tmpl.h @@ -0,0 +1,7 @@ +namespace saw { +namespace impl { +struct forst_decode { + +}; +} +} diff --git a/modules/codec/c++/interface.h b/modules/codec/c++/interface.h new file mode 100644 index 0000000..b1422a9 --- /dev/null +++ b/modules/codec/c++/interface.h @@ -0,0 +1,103 @@ +#pragma once + +#include +#include "schema.h" +#include "data.h" + +namespace saw { +template +class function; + +template +class function, Encode, Func> { +private: + Func func_; +public: + function(Func func): + func_{std::move(func)} + {} + + error_or> call(data req){ + return func_(std::move(req)); + } +}; + +template +class interface; + +template +class interface, Names>...>, Encode, Funcs...> { +private: + std::tuple, Encode, Funcs>...> funcs_; +public: + interface(function, Encode, Funcs>... funcs): + funcs_{std::move(funcs)...} + {} + + /** + * Get the function based on the string literal matching the position in the tuple + */ + template + function< + schema::Function< + typename parameter_pack_type< + parameter_key_pack_index< + Lit, Names... + >::value + , Requests...>::type + , + typename parameter_pack_type< + parameter_key_pack_index< + Lit, Names... + >::value + , Responses...>::type + > + , + Encode + , + typename parameter_pack_type< + parameter_key_pack_index< + Lit, Names... + >::value + , Funcs...>::type + >& get(){ + return std::get::value>(funcs_); + } + + template + error_or::value + , Responses...>::type + , Encode>> call( + data< + typename parameter_pack_type< + parameter_key_pack_index< + Lit, Names... + >::value + , Requests...>::type + , Encode> req + ){ + return get().call(std::move(req)); + } + +}; + +template +struct function_factory { + template + static function create(Func func){ + return function{std::move(func)}; + } +}; + +template +struct interface_factory { + template + static interface create(Func... func){ + return interface{std::move(func)...}; + } +}; +} diff --git a/modules/codec/c++/rpc.h b/modules/codec/c++/rpc.h new file mode 100644 index 0000000..b21ecf8 --- /dev/null +++ b/modules/codec/c++/rpc.h @@ -0,0 +1,26 @@ +#pragma once + +namespace saw { +template +class remote { + static_assert(always_false, "Type of remote not supported"); +}; + +template +class rpc_client { + template + struct request { + private: + std::tuple> ids_; + public: + error_or> wait(); + }; + + template + request request_data(id... data); +}; + +template +class rpc_server { +}; +} diff --git a/modules/codec/c++/schema.h b/modules/codec/c++/schema.h new file mode 100644 index 0000000..a8494fe --- /dev/null +++ b/modules/codec/c++/schema.h @@ -0,0 +1,109 @@ +#pragma once + +#include +#include + +namespace saw { +namespace schema { +// NOLINTBEGIN +template struct Member {}; + +template struct Struct { + static_assert( + always_false, + "This schema template doesn't support this type of template argument"); +}; + +template +struct Struct...> {}; + +template struct Union { + static_assert( + always_false, + "This schema template doesn't support this type of template argument"); +}; + +template +struct Union...> {}; + +template struct Array {}; + +template struct is_array { + constexpr static bool value = false; +}; + +template struct is_array> { + constexpr static bool value = true; +}; + +template struct FixedArray {}; + +template struct Tuple {}; + +/** + * This acts as a separator of different encodings being mashed together + * For example we can transport any base64 encodings in JSON + * + * using WrappedExample = schema::Tuple< + * schema::Wrapper + * >; + * + * data ex_data; + */ +template +class Wrapper {}; + +struct String {}; + +struct SignedInteger {}; +struct UnsignedInteger {}; +struct FloatingPoint {}; + +template struct Primitive { + static_assert(((std::is_same_v || + std::is_same_v)&&(N == 1 || N == 2 || + N == 4 || N == 8)) || + (std::is_same_v && (N == 4 || N == 8)), + "Primitive Type is not supported"); +}; + +using Int8 = Primitive; +using Int16 = Primitive; +using Int32 = Primitive; +using Int64 = Primitive; + +using UInt8 = Primitive; +using UInt16 = Primitive; +using UInt32 = Primitive; +using UInt64 = Primitive; + +using Float32 = Primitive; +using Float64 = Primitive; + +/** + * Classes allowing to distinguish Ints from VarInts + */ +template +struct VariableLengthPrimitive {}; + +using VarInt = VariableLengthPrimitive; +using VarLong = VariableLengthPrimitive; + +/** + * Classes enabling Rpc calls + */ +template +struct Function {}; + +template struct Interface { + static_assert( + always_false, + "This schema template doesn't support this type of template argument"); +}; + +template +struct Interface,Names>...> {}; + +// NOLINTEND +} // namespace schema +} // namespace saw diff --git a/modules/codec/c++/schema_hash.h b/modules/codec/c++/schema_hash.h new file mode 100644 index 0000000..5690166 --- /dev/null +++ b/modules/codec/c++/schema_hash.h @@ -0,0 +1,105 @@ +#pragma once + +#include "schema.h" + +namespace saw { +struct schema_hash_combine { + static constexpr uint64_t apply(uint64_t seed, uint64_t v){ + return (seed ^ v) * 1099511628211u; + + + return seed ^( std::hash{}(v) + 0x9e3779b9 + (seed<<6) + (seed >> 2)); + } +}; + +template +struct schema_hash { + static_assert(always_false, "Not schema_hashable"); +}; + +template<> +struct schema_hash> { + static constexpr uint64_t base_value = 0u; +}; + +template<> +struct schema_hash> { + static constexpr uint64_t base_value = 1u; +}; + +template<> +struct schema_hash> { + static constexpr uint64_t base_value = 2u; +}; + +template<> +struct schema_hash> { + static constexpr uint64_t base_value = 3u; +}; + +template<> +struct schema_hash> { + static constexpr uint64_t base_value = 4u; +}; + +template<> +struct schema_hash> { + static constexpr uint64_t base_value = 5u; +}; + +template<> +struct schema_hash> { + static constexpr uint64_t base_value = 6u; +}; + +template<> +struct schema_hash> { + static constexpr uint64_t base_value = 7u; +}; + +template<> +struct schema_hash> { + static constexpr uint64_t base_value = 8u; +}; + +template<> +struct schema_hash> { + static constexpr uint64_t base_value = 9u; +}; + +template +struct schema_hash> { + static constexpr uint64_t base_value = 10u; +}; + +template +struct schema_hash...>> { + static constexpr uint64_t base_value = 11u; +}; + +template +struct schema_hash...>> { + static constexpr uint64_t base_value = 12u; +}; + +template +struct schema_hash> { + static constexpr uint64_t base_value = 13u; +}; + +template<> +struct schema_hash { + static constexpr uint64_t base_value = 14u; +}; + +template +struct schema_hash> { + static constexpr uint64_t base_value = 15u; +}; + +template +struct schema_hash> { + static constexpr uint64_t base_value = 16u; +}; + +} diff --git a/modules/codec/c++/schema_stringify.h b/modules/codec/c++/schema_stringify.h new file mode 100644 index 0000000..a82081a --- /dev/null +++ b/modules/codec/c++/schema_stringify.h @@ -0,0 +1,118 @@ +#pragma once + +#include "schema.h" + +#include +#include + +namespace saw { +template +struct schema_stringify { + static_assert(always_false, "Not supported"); +}; + +template +struct schema_stringify> { + static void apply(std::stringstream& iss) { + iss << "saw::schema::Array<"; + schema_stringify::apply(iss); + iss << ","; + iss << ct_convert_to_digits::literal.view(); + iss << ">"; + } +}; + +template +struct schema_stringify> { + static void apply(std::stringstream& iss) { + iss << "saw::schema::Primitive<"; + schema_stringify::apply(iss); + iss << ","; + iss << ct_convert_to_digits::literal.view(); + iss << ">"; + } +}; + +template<> +struct schema_stringify { + static void apply(std::stringstream& iss) { + iss << "saw:schema::SignedInteger"; + } +}; + +template<> +struct schema_stringify { + static void apply(std::stringstream& iss) { + iss << "saw:schema::UnsignedInteger"; + } +}; + +template<> +struct schema_stringify { + static void apply(std::stringstream& iss) { + iss << "saw:schema::FloatingPoint"; + } +}; + +template +struct schema_stringify_member { + static void apply(std::stringstream& iss) { + (void)iss; + } +}; + +template +struct schema_stringify_member, TL...> { + + static void apply(std::stringstream& iss) { + iss << "saw::schema::Member<"; + schema_stringify::apply(iss); + iss << ",\""; + iss << Name.view(); + iss << "\">"; + if constexpr ( sizeof...(TL) > 0){ + iss << ","; + schema_stringify_member::apply(iss); + } + } +}; + +template +struct schema_stringify...>> { + static void apply(std::stringstream& iss) { + iss << "saw::schema::Struct<"; + schema_stringify_member...>::apply(iss); + iss << ">"; + } +}; + +template +struct schema_stringify...>> { + static void apply(std::stringstream& iss) { + iss << "saw::schema::Union<"; + schema_stringify_member...>::apply(iss); + iss << ">"; + } +}; + +template +struct schema_stringify> { + static void apply(std::stringstream& iss){ + iss << "saw::schema::Function<"; + schema_stringify::apply(iss); + iss << ","; + schema_stringify::apply(iss); + iss << ">"; + } +}; + +template +struct schema_stringify...>>{ + static void apply(std::stringstream& iss){ + iss << "saw::schema::Interface<"; + schema_stringify_member...>::apply(iss); + iss << ">"; + } +}; + +} diff --git a/modules/codec/c++/simple.h b/modules/codec/c++/simple.h new file mode 100644 index 0000000..8760754 --- /dev/null +++ b/modules/codec/c++/simple.h @@ -0,0 +1,389 @@ +#pragma once + +#include "data.h" +#include "stream_value.h" + +#include +#include + +namespace saw { +namespace encode { +struct KelSimple {}; +} + +template +class data { +private: + ring_buffer buffer_; +public: + data() = default; + + buffer& get_buffer(){ + return buffer_; + } +}; + +namespace impl { +template +class kelsimple_encode { + static_assert(always_false, "This schema type is not being handled by the kelsimple encoding."); +}; + +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(eov.is_error()){ + return eov; + } + } + 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...>,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; + if (from.template holds_alternative()) { + { + auto eov = stream_value::encode(static_cast(i), to); + if(eov.is_error()){ + return eov; + } + } + { + auto eov = kelsimple_encode::encode(from.template get(), to); + if(eov.is_error()){ + return eov; + } + } + } + + 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, 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."); +}; + +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(eov.is_error()){ + return eov; + } + } + 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...>,FromEnc> { + template + static error_or decode_member(buffer& from, data...>, FromEnc>& to, uint64_t val){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Literal = parameter_key_pack_type::literal; + + if( i == val ){ + to.template set(data{}); + auto eov = kelsimple_decode::decode(from, to.template get()); + if(eov.is_error()){ + return eov; + } + return void_t{}; + } + + if constexpr ((i+1) < sizeof...(T)){ + auto eov = decode_member(from, to, val); + if(eov.is_error()){ + return eov; + } + } + return void_t{}; + + } + static error_or decode(buffer& from, data...>, FromEnc>& to){ + uint64_t val{}; + auto eov = stream_value::decode(val, from); + if(eov.is_error()){ + return eov; + } + if ( val >= sizeof...(T) ){ + return make_error(); + } + return decode_member<0>(from, to, val); + } + +}; + +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 +class codec { +public: + struct config { + size_t depth = 16; + size_t length = 1024; + }; +private: + config cfg_; +public: + codec() = default; + + SAW_FORBID_COPY(codec); + SAW_DEFAULT_MOVE(codec); + + template + error_or encode(const data& from_enc, data& to_enc){ + buffer_view buff_v{to_enc.get_buffer()}; + + auto eov = impl::kelsimple_encode::encode(from_enc, buff_v); + + 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; + } +}; +} diff --git a/modules/codec/c++/stream_value.h b/modules/codec/c++/stream_value.h new file mode 100644 index 0000000..09203cb --- /dev/null +++ b/modules/codec/c++/stream_value.h @@ -0,0 +1,64 @@ +#pragma once + +#include "schema.h" + +#include +#include + +#include +#include + +namespace saw { +/** + * Helper class to encode/decode any primtive type into/from litte endian. + * The shift class does this by shifting bytes. This type of procedure is + * platform independent. So it does not matter if the memory layout is + * little endian or big endian + */ +template class shift_stream_value { + static_assert(always_false, "Shift Stream Value only supports Primitives"); +}; + +template class shift_stream_value> { +public: + inline static error_or decode(typename native_data_type>::type &val, buffer &buff) { + if (buff.read_composite_length() < N) { + return make_error(); + } + + typename native_data_type>::type raw = 0; + + for (size_t i = 0; i < N; ++i) { + raw |= (static_cast>::type>(buff.read(i)) << (i * 8)); + } + + memcpy(&val, &raw, N); + buff.read_advance(N); + + return void_t{}; + } + + inline static error_or encode(const typename native_data_type>::type &val, buffer &buff) { + error err = buff.write_require_length(N); + if (err.failed()) { + return err; + } + + typename native_data_type>::type raw{}; + memcpy(&raw, &val, N); + + for (size_t i = 0; i < N; ++i) { + buff.write(i) = raw >> (i * 8); + } + + buff.write_advance(N); + + return void_t{}; + } + + inline static size_t size() { return N; } +}; + +template using stream_value = shift_stream_value; + +} // namespace saw diff --git a/modules/codec/csv.h b/modules/codec/csv.h deleted file mode 100644 index 67c2c1d..0000000 --- a/modules/codec/csv.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "data.h" - -namespace saw { -namespace encode { -struct Csv {}; -} - -template -class codec { -public: - template - static error_or encode(const data& from, data& to){ - - return make_error(); - } - - template - static error_or decode(data& from, data& to){ - - return make_error(); - } -}; -} diff --git a/modules/codec/data.h b/modules/codec/data.h deleted file mode 100644 index 237ef5a..0000000 --- a/modules/codec/data.h +++ /dev/null @@ -1,370 +0,0 @@ -#pragma once - -#include -#include - -#include - -#include -#include -#include -#include - -#include "schema.h" - -namespace saw { -namespace encode { -struct Native {}; -} -template -class codec; -/* - * Helper for the basic message container, so the class doesn't have to be - * specialized 10 times. - */ -template struct native_data_type; - -template <> -struct native_data_type> { - using type = int8_t; -}; - -template <> -struct native_data_type> { - using type = int16_t; -}; - -template <> -struct native_data_type> { - using type = int32_t; -}; - -template <> -struct native_data_type> { - using type = int64_t; -}; - -template <> -struct native_data_type> { - using type = uint8_t; -}; - -template <> -struct native_data_type> { - using type = uint16_t; -}; - -template <> -struct native_data_type> { - using type = uint32_t; -}; - -template <> -struct native_data_type> { - using type = uint64_t; -}; - -template <> -struct native_data_type> { - using type = float; -}; - -template <> -struct native_data_type> { - using type = double; -}; - -template -class data { -private: - static_assert(always_false, "Type not supported"); -}; - -template -class data...>, encode::Native> { -private: - std::variant...> value_; -public: - data() = default; - - SAW_DEFAULT_COPY(data); - SAW_DEFAULT_MOVE(data); - - template - void set(data::value, T...>::type, encode::Native> val){ - value_ = std::move(val); - } - - template - data::value, T...>::type, encode::Native>& init(){ - value_ = data::value, T...>::type, encode::Native>{}; - return get(); - } - - template - bool holds_alternative() const { - return (parameter_key_pack_index::value == value_.index()); - } - - template - data::value, T...>::type, encode::Native>& get(){ - return std::get::value>(value_); - } - - template - const data::value, T...>::type, encode::Native>& get() const{ - return std::get::value>(value_); - } -}; - -template -class data...>, encode::Native> { -private: - std::tuple...> value_; -public: - data() = default; - SAW_DEFAULT_COPY(data); - SAW_DEFAULT_MOVE(data); - - template - data< - typename parameter_pack_type< - parameter_key_pack_index< - literal, literals... - >::value - , T...>::type - , encode::Native>& get(){ - return std::get::value>(value_); - } - - template - const data< - typename parameter_pack_type< - parameter_key_pack_index< - literal, literals... - >::value - , T...>::type - , encode::Native>& get() const { - return std::get::value>(value_); - } - - constexpr size_t size() const { - return sizeof...(T); - } -}; - -template -class data, encode::Native> { -private: - std::tuple...> value_; -public: - data() = default; - SAW_DEFAULT_COPY(data); - SAW_DEFAULT_MOVE(data); - - template - data::type, encode::Native>& get(){ - return std::get(value_); - } - - template - const data::type, encode::Native>& get() const{ - return std::get(value_); - } - - constexpr size_t size() const { - return sizeof...(T); - } -}; - -template -class data, encode::Native> { - private: - std::array dims_; - std::vector> value_; - - std::size_t get_full_size() const { - std::size_t s = 1; - - for(std::size_t iter = 0; iter < Dim; ++iter){ - assert(dims_.at(iter) > 0); - s *= dims_.at(iter); - } - - return s; - } - public: - data() = default; - SAW_DEFAULT_COPY(data); - SAW_DEFAULT_MOVE(data); - - data(const std::array& i): - dims_{i}, - value_{} - { - value_.resize(get_full_size()); - } - - template - data(Dims... size_): - data{{size_...}} - { - static_assert(sizeof...(Dims)==Dim, "Argument size must be equal to the Dimension"); - } - - data& at(const std::array& ind){ - return value_.at(this->get_flat_index(ind)); - } - - const data& at(const std::array& ind) const { - return value_.at(this->get_flat_index(ind)); - } - - template - data& at(Dims... i){ - return value_.at(this->get_flat_index({i...})); - } - - template - const data& at(Dims... i) const { - return value_.at(this->get_flat_index({i...})); - } - - std::size_t get_dim_size(std::size_t i) const { - return dims_.at(i); - } - - size_t size() const { return value_.size();} - -private: - std::size_t get_flat_index(const std::array& i) const { - std::size_t s = 0; - - std::size_t stride = 1; - - for(std::size_t iter = 0; iter < Dim; ++iter){ - assert(i.at(iter) < dims_.at(iter)); - s += i.at(iter) * stride; - stride *= dims_.at(iter); - } - - return s; - } -}; - -template -class data, encode::Native> { -private: - //using inner_type = std::array, multiply_helper::value>; - //std::unique_ptr value_; - std::vector> value_; - -public: - data(){ - value_.resize(ct_multiply::value); - } - - data& at(const std::array& ind){ - return value_.at(this->get_flat_index(ind)); - } - - const data& at(const std::array& ind) const { - return value_.at(this->get_flat_index(ind)); - } - - template - data& at(Dims... i) { - return value_.at(this->get_flat_index({i...})); - } - - template - const data& at(Dims... i) const { - return value_.at(this->get_flat_index({i...})); - } - - template - std::size_t get_dim_size() const { - return parameter_pack_value::value; - } -private: - std::size_t get_flat_index(const std::array& i) const { - std::size_t s = 0; - - std::size_t stride = 1; - - constexpr static std::array dims_{D...}; - - for(std::size_t iter = 0; iter < sizeof...(D); ++iter){ - assert(i.at(iter) < dims_.at(iter)); - s += i.at(iter) * stride; - stride *= dims_.at(iter); - } - - return s; - } -}; - -template<> -class data { -private: - std::string value_; -public: - data() = default; - SAW_DEFAULT_COPY(data); - 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(); - } - - void set(std::string str){ - 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); - } - - void set_at(size_t i, char val){ - value_.at(i) = val; - } - - bool operator==(const std::string_view& val)const{ - return value_ == val; - } -}; - -template -class data, encode::Native> { -private: - typename native_data_type>::type value_; -public: - data():value_{{}}{}; - SAW_DEFAULT_COPY(data); - SAW_DEFAULT_MOVE(data); - - data(typename native_data_type>::type value__): - value_{std::move(value__)}{} - - void set(typename native_data_type>::type val){ - value_ = val; - } - - typename native_data_type>::type get() const {return value_;} -}; - - -} diff --git a/modules/codec/forst.h b/modules/codec/forst.h deleted file mode 100644 index 7e8fbf0..0000000 --- a/modules/codec/forst.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "data.h" - -namespace saw { -namespace encode { -struct KelForst {}; -} -} - -#include "forst.tmpl.hpp" - -namespace saw { -class data { -private: - own buff_; -public: - data(own buff): - buff_{std::move(buff)} - {} -}; - -template -class data...>, encode::KelForst> { -private: - own buff_; -public: - data(own buff): - buff_{std::move(buff)} - {} -}; -} diff --git a/modules/codec/forst.tmpl.h b/modules/codec/forst.tmpl.h deleted file mode 100644 index 30d18ef..0000000 --- a/modules/codec/forst.tmpl.h +++ /dev/null @@ -1,7 +0,0 @@ -namespace saw { -namespace impl { -struct forst_decode { - -}; -} -} diff --git a/modules/codec/interface.h b/modules/codec/interface.h deleted file mode 100644 index b1422a9..0000000 --- a/modules/codec/interface.h +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -#include -#include "schema.h" -#include "data.h" - -namespace saw { -template -class function; - -template -class function, Encode, Func> { -private: - Func func_; -public: - function(Func func): - func_{std::move(func)} - {} - - error_or> call(data req){ - return func_(std::move(req)); - } -}; - -template -class interface; - -template -class interface, Names>...>, Encode, Funcs...> { -private: - std::tuple, Encode, Funcs>...> funcs_; -public: - interface(function, Encode, Funcs>... funcs): - funcs_{std::move(funcs)...} - {} - - /** - * Get the function based on the string literal matching the position in the tuple - */ - template - function< - schema::Function< - typename parameter_pack_type< - parameter_key_pack_index< - Lit, Names... - >::value - , Requests...>::type - , - typename parameter_pack_type< - parameter_key_pack_index< - Lit, Names... - >::value - , Responses...>::type - > - , - Encode - , - typename parameter_pack_type< - parameter_key_pack_index< - Lit, Names... - >::value - , Funcs...>::type - >& get(){ - return std::get::value>(funcs_); - } - - template - error_or::value - , Responses...>::type - , Encode>> call( - data< - typename parameter_pack_type< - parameter_key_pack_index< - Lit, Names... - >::value - , Requests...>::type - , Encode> req - ){ - return get().call(std::move(req)); - } - -}; - -template -struct function_factory { - template - static function create(Func func){ - return function{std::move(func)}; - } -}; - -template -struct interface_factory { - template - static interface create(Func... func){ - return interface{std::move(func)...}; - } -}; -} diff --git a/modules/codec/rpc.h b/modules/codec/rpc.h deleted file mode 100644 index b21ecf8..0000000 --- a/modules/codec/rpc.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -namespace saw { -template -class remote { - static_assert(always_false, "Type of remote not supported"); -}; - -template -class rpc_client { - template - struct request { - private: - std::tuple> ids_; - public: - error_or> wait(); - }; - - template - request request_data(id... data); -}; - -template -class rpc_server { -}; -} diff --git a/modules/codec/schema.h b/modules/codec/schema.h deleted file mode 100644 index a8494fe..0000000 --- a/modules/codec/schema.h +++ /dev/null @@ -1,109 +0,0 @@ -#pragma once - -#include -#include - -namespace saw { -namespace schema { -// NOLINTBEGIN -template struct Member {}; - -template struct Struct { - static_assert( - always_false, - "This schema template doesn't support this type of template argument"); -}; - -template -struct Struct...> {}; - -template struct Union { - static_assert( - always_false, - "This schema template doesn't support this type of template argument"); -}; - -template -struct Union...> {}; - -template struct Array {}; - -template struct is_array { - constexpr static bool value = false; -}; - -template struct is_array> { - constexpr static bool value = true; -}; - -template struct FixedArray {}; - -template struct Tuple {}; - -/** - * This acts as a separator of different encodings being mashed together - * For example we can transport any base64 encodings in JSON - * - * using WrappedExample = schema::Tuple< - * schema::Wrapper - * >; - * - * data ex_data; - */ -template -class Wrapper {}; - -struct String {}; - -struct SignedInteger {}; -struct UnsignedInteger {}; -struct FloatingPoint {}; - -template struct Primitive { - static_assert(((std::is_same_v || - std::is_same_v)&&(N == 1 || N == 2 || - N == 4 || N == 8)) || - (std::is_same_v && (N == 4 || N == 8)), - "Primitive Type is not supported"); -}; - -using Int8 = Primitive; -using Int16 = Primitive; -using Int32 = Primitive; -using Int64 = Primitive; - -using UInt8 = Primitive; -using UInt16 = Primitive; -using UInt32 = Primitive; -using UInt64 = Primitive; - -using Float32 = Primitive; -using Float64 = Primitive; - -/** - * Classes allowing to distinguish Ints from VarInts - */ -template -struct VariableLengthPrimitive {}; - -using VarInt = VariableLengthPrimitive; -using VarLong = VariableLengthPrimitive; - -/** - * Classes enabling Rpc calls - */ -template -struct Function {}; - -template struct Interface { - static_assert( - always_false, - "This schema template doesn't support this type of template argument"); -}; - -template -struct Interface,Names>...> {}; - -// NOLINTEND -} // namespace schema -} // namespace saw diff --git a/modules/codec/schema_hash.h b/modules/codec/schema_hash.h deleted file mode 100644 index 5690166..0000000 --- a/modules/codec/schema_hash.h +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -#include "schema.h" - -namespace saw { -struct schema_hash_combine { - static constexpr uint64_t apply(uint64_t seed, uint64_t v){ - return (seed ^ v) * 1099511628211u; - - - return seed ^( std::hash{}(v) + 0x9e3779b9 + (seed<<6) + (seed >> 2)); - } -}; - -template -struct schema_hash { - static_assert(always_false, "Not schema_hashable"); -}; - -template<> -struct schema_hash> { - static constexpr uint64_t base_value = 0u; -}; - -template<> -struct schema_hash> { - static constexpr uint64_t base_value = 1u; -}; - -template<> -struct schema_hash> { - static constexpr uint64_t base_value = 2u; -}; - -template<> -struct schema_hash> { - static constexpr uint64_t base_value = 3u; -}; - -template<> -struct schema_hash> { - static constexpr uint64_t base_value = 4u; -}; - -template<> -struct schema_hash> { - static constexpr uint64_t base_value = 5u; -}; - -template<> -struct schema_hash> { - static constexpr uint64_t base_value = 6u; -}; - -template<> -struct schema_hash> { - static constexpr uint64_t base_value = 7u; -}; - -template<> -struct schema_hash> { - static constexpr uint64_t base_value = 8u; -}; - -template<> -struct schema_hash> { - static constexpr uint64_t base_value = 9u; -}; - -template -struct schema_hash> { - static constexpr uint64_t base_value = 10u; -}; - -template -struct schema_hash...>> { - static constexpr uint64_t base_value = 11u; -}; - -template -struct schema_hash...>> { - static constexpr uint64_t base_value = 12u; -}; - -template -struct schema_hash> { - static constexpr uint64_t base_value = 13u; -}; - -template<> -struct schema_hash { - static constexpr uint64_t base_value = 14u; -}; - -template -struct schema_hash> { - static constexpr uint64_t base_value = 15u; -}; - -template -struct schema_hash> { - static constexpr uint64_t base_value = 16u; -}; - -} diff --git a/modules/codec/schema_stringify.h b/modules/codec/schema_stringify.h deleted file mode 100644 index a82081a..0000000 --- a/modules/codec/schema_stringify.h +++ /dev/null @@ -1,118 +0,0 @@ -#pragma once - -#include "schema.h" - -#include -#include - -namespace saw { -template -struct schema_stringify { - static_assert(always_false, "Not supported"); -}; - -template -struct schema_stringify> { - static void apply(std::stringstream& iss) { - iss << "saw::schema::Array<"; - schema_stringify::apply(iss); - iss << ","; - iss << ct_convert_to_digits::literal.view(); - iss << ">"; - } -}; - -template -struct schema_stringify> { - static void apply(std::stringstream& iss) { - iss << "saw::schema::Primitive<"; - schema_stringify::apply(iss); - iss << ","; - iss << ct_convert_to_digits::literal.view(); - iss << ">"; - } -}; - -template<> -struct schema_stringify { - static void apply(std::stringstream& iss) { - iss << "saw:schema::SignedInteger"; - } -}; - -template<> -struct schema_stringify { - static void apply(std::stringstream& iss) { - iss << "saw:schema::UnsignedInteger"; - } -}; - -template<> -struct schema_stringify { - static void apply(std::stringstream& iss) { - iss << "saw:schema::FloatingPoint"; - } -}; - -template -struct schema_stringify_member { - static void apply(std::stringstream& iss) { - (void)iss; - } -}; - -template -struct schema_stringify_member, TL...> { - - static void apply(std::stringstream& iss) { - iss << "saw::schema::Member<"; - schema_stringify::apply(iss); - iss << ",\""; - iss << Name.view(); - iss << "\">"; - if constexpr ( sizeof...(TL) > 0){ - iss << ","; - schema_stringify_member::apply(iss); - } - } -}; - -template -struct schema_stringify...>> { - static void apply(std::stringstream& iss) { - iss << "saw::schema::Struct<"; - schema_stringify_member...>::apply(iss); - iss << ">"; - } -}; - -template -struct schema_stringify...>> { - static void apply(std::stringstream& iss) { - iss << "saw::schema::Union<"; - schema_stringify_member...>::apply(iss); - iss << ">"; - } -}; - -template -struct schema_stringify> { - static void apply(std::stringstream& iss){ - iss << "saw::schema::Function<"; - schema_stringify::apply(iss); - iss << ","; - schema_stringify::apply(iss); - iss << ">"; - } -}; - -template -struct schema_stringify...>>{ - static void apply(std::stringstream& iss){ - iss << "saw::schema::Interface<"; - schema_stringify_member...>::apply(iss); - iss << ">"; - } -}; - -} diff --git a/modules/codec/simple.h b/modules/codec/simple.h deleted file mode 100644 index 8760754..0000000 --- a/modules/codec/simple.h +++ /dev/null @@ -1,389 +0,0 @@ -#pragma once - -#include "data.h" -#include "stream_value.h" - -#include -#include - -namespace saw { -namespace encode { -struct KelSimple {}; -} - -template -class data { -private: - ring_buffer buffer_; -public: - data() = default; - - buffer& get_buffer(){ - return buffer_; - } -}; - -namespace impl { -template -class kelsimple_encode { - static_assert(always_false, "This schema type is not being handled by the kelsimple encoding."); -}; - -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(eov.is_error()){ - return eov; - } - } - 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...>,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; - if (from.template holds_alternative()) { - { - auto eov = stream_value::encode(static_cast(i), to); - if(eov.is_error()){ - return eov; - } - } - { - auto eov = kelsimple_encode::encode(from.template get(), to); - if(eov.is_error()){ - return eov; - } - } - } - - 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, 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."); -}; - -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(eov.is_error()){ - return eov; - } - } - 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...>,FromEnc> { - template - static error_or decode_member(buffer& from, data...>, FromEnc>& to, uint64_t val){ - using Type = typename parameter_pack_type::type; - constexpr string_literal Literal = parameter_key_pack_type::literal; - - if( i == val ){ - to.template set(data{}); - auto eov = kelsimple_decode::decode(from, to.template get()); - if(eov.is_error()){ - return eov; - } - return void_t{}; - } - - if constexpr ((i+1) < sizeof...(T)){ - auto eov = decode_member(from, to, val); - if(eov.is_error()){ - return eov; - } - } - return void_t{}; - - } - static error_or decode(buffer& from, data...>, FromEnc>& to){ - uint64_t val{}; - auto eov = stream_value::decode(val, from); - if(eov.is_error()){ - return eov; - } - if ( val >= sizeof...(T) ){ - return make_error(); - } - return decode_member<0>(from, to, val); - } - -}; - -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 -class codec { -public: - struct config { - size_t depth = 16; - size_t length = 1024; - }; -private: - config cfg_; -public: - codec() = default; - - SAW_FORBID_COPY(codec); - SAW_DEFAULT_MOVE(codec); - - template - error_or encode(const data& from_enc, data& to_enc){ - buffer_view buff_v{to_enc.get_buffer()}; - - auto eov = impl::kelsimple_encode::encode(from_enc, buff_v); - - 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; - } -}; -} diff --git a/modules/codec/stream_value.h b/modules/codec/stream_value.h deleted file mode 100644 index 09203cb..0000000 --- a/modules/codec/stream_value.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "schema.h" - -#include -#include - -#include -#include - -namespace saw { -/** - * Helper class to encode/decode any primtive type into/from litte endian. - * The shift class does this by shifting bytes. This type of procedure is - * platform independent. So it does not matter if the memory layout is - * little endian or big endian - */ -template class shift_stream_value { - static_assert(always_false, "Shift Stream Value only supports Primitives"); -}; - -template class shift_stream_value> { -public: - inline static error_or decode(typename native_data_type>::type &val, buffer &buff) { - if (buff.read_composite_length() < N) { - return make_error(); - } - - typename native_data_type>::type raw = 0; - - for (size_t i = 0; i < N; ++i) { - raw |= (static_cast>::type>(buff.read(i)) << (i * 8)); - } - - memcpy(&val, &raw, N); - buff.read_advance(N); - - return void_t{}; - } - - inline static error_or encode(const typename native_data_type>::type &val, buffer &buff) { - error err = buff.write_require_length(N); - if (err.failed()) { - return err; - } - - typename native_data_type>::type raw{}; - memcpy(&raw, &val, N); - - for (size_t i = 0; i < N; ++i) { - buff.write(i) = raw >> (i * 8); - } - - buff.write_advance(N); - - return void_t{}; - } - - inline static size_t size() { return N; } -}; - -template using stream_value = shift_stream_value; - -} // namespace saw diff --git a/modules/codec/tests/SConscript b/modules/codec/tests/SConscript new file mode 100644 index 0000000..ba09372 --- /dev/null +++ b/modules/codec/tests/SConscript @@ -0,0 +1,29 @@ +#!/bin/false + +import os +import os.path +import glob + + +Import('env') + +dir_path = Dir('.').abspath + +# Environment for base library +test_cases_env = env.Clone(); + +test_cases_env.sources = sorted(glob.glob(dir_path + "/*.cpp")) +test_cases_env.headers = sorted(glob.glob(dir_path + "/*.h")) + +env.sources += test_cases_env.sources; +env.headers += test_cases_env.headers; + +objects_static = [] +test_cases_env.add_source_files(objects_static, test_cases_env.sources, shared=False); +test_cases_env.program = test_cases_env.Program('#bin/tests', [objects_static, env.library_static]); + +# Set Alias +env.Alias('test', test_cases_env.program); +env.Alias('check', test_cases_env.program); + +env.targets += ['test','check']; -- cgit v1.2.3