From 8dad985328e2183b224300aa992951131956fdb3 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Tue, 23 Jan 2024 13:12:11 +0100 Subject: core,codec-json,codec-minecraft,codec-netcdf,codec,io-tls,io,io_codec,window,window-opengl: Renamed file endings and changed includes --- modules/codec-json/c++/json.h | 120 ----- modules/codec-json/c++/json.hpp | 120 +++++ modules/codec-json/c++/json.tmpl.h | 734 ------------------------------- modules/codec-json/c++/json.tmpl.hpp | 734 +++++++++++++++++++++++++++++++ modules/codec-minecraft/minecraft.h | 116 ----- modules/codec-minecraft/minecraft.hpp | 116 +++++ modules/codec-minecraft/var_int_data.h | 31 -- modules/codec-minecraft/var_int_data.hpp | 31 ++ modules/codec-netcdf/c++/netcdf.h | 151 ------- modules/codec-netcdf/c++/netcdf.hpp | 151 +++++++ modules/codec-netcdf/c++/netcdf.tmpl.h | 348 --------------- modules/codec-netcdf/c++/netcdf.tmpl.hpp | 348 +++++++++++++++ modules/codec/c++/args.h | 123 ------ modules/codec/c++/args.hpp | 123 ++++++ modules/codec/c++/crc32.h | 114 ----- modules/codec/c++/crc32.hpp | 114 +++++ modules/codec/c++/csv.h | 216 --------- modules/codec/c++/csv.hpp | 216 +++++++++ modules/codec/c++/data.h | 451 ------------------- modules/codec/c++/data.hpp | 451 +++++++++++++++++++ modules/codec/c++/forst.h | 32 -- modules/codec/c++/forst.hpp | 32 ++ modules/codec/c++/forst.tmpl.h | 7 - modules/codec/c++/forst.tmpl.hpp | 7 + modules/codec/c++/interface.h | 103 ----- modules/codec/c++/interface.hpp | 103 +++++ modules/codec/c++/rpc.h | 29 -- modules/codec/c++/rpc.hpp | 29 ++ modules/codec/c++/schema.h | 172 -------- modules/codec/c++/schema.hpp | 172 ++++++++ modules/codec/c++/schema_factory.h | 49 --- modules/codec/c++/schema_factory.hpp | 49 +++ modules/codec/c++/schema_hash.h | 207 --------- modules/codec/c++/schema_hash.hpp | 207 +++++++++ modules/codec/c++/schema_stringify.h | 118 ----- modules/codec/c++/schema_stringify.hpp | 118 +++++ modules/codec/c++/simple.h | 389 ---------------- modules/codec/c++/simple.hpp | 389 ++++++++++++++++ modules/codec/c++/stream_value.h | 64 --- modules/codec/c++/stream_value.hpp | 64 +++ modules/core/c++/test/suite.h | 43 -- modules/core/c++/test/suite.hpp | 43 ++ modules/device-hip/c++/rpc.h | 47 -- modules/device-hip/c++/rpc.hpp | 47 ++ modules/io-tls/tls.h | 68 --- modules/io-tls/tls.hpp | 68 +++ modules/io/io.h | 219 --------- modules/io/io.hpp | 219 +++++++++ modules/io/io_helpers.h | 53 --- modules/io/io_helpers.hpp | 53 +++ modules/io_codec/io_peer.h | 104 ----- modules/io_codec/io_peer.hpp | 104 +++++ modules/io_codec/io_peer.tmpl.h | 117 ----- modules/io_codec/io_peer.tmpl.hpp | 117 +++++ modules/io_codec/rpc.h | 31 -- modules/io_codec/rpc.hpp | 31 ++ modules/window-opengl/gl_backends.h | 10 - modules/window-opengl/gl_backends.hpp | 10 + modules/window-opengl/gl_context.h | 43 -- modules/window-opengl/gl_context.hpp | 43 ++ modules/window-opengl/gl_window.h | 8 - modules/window-opengl/gl_window.hpp | 8 + modules/window-opengl/gl_xcb.h | 68 --- modules/window-opengl/gl_xcb.hpp | 68 +++ modules/window/c++/backends.h | 10 - modules/window/c++/backends.hpp | 10 + modules/window/c++/device.h | 18 - modules/window/c++/device.hpp | 18 + modules/window/c++/linux_xcb.h | 5 - modules/window/c++/linux_xcb.hpp | 5 + modules/window/c++/video_mode.h | 11 - modules/window/c++/video_mode.hpp | 11 + modules/window/c++/window.h | 79 ---- modules/window/c++/window.hpp | 79 ++++ modules/window/c++/xcb.h | 105 ----- modules/window/c++/xcb.hpp | 105 +++++ 76 files changed, 4613 insertions(+), 4613 deletions(-) delete mode 100644 modules/codec-json/c++/json.h create mode 100644 modules/codec-json/c++/json.hpp delete mode 100644 modules/codec-json/c++/json.tmpl.h create mode 100644 modules/codec-json/c++/json.tmpl.hpp delete mode 100644 modules/codec-minecraft/minecraft.h create mode 100644 modules/codec-minecraft/minecraft.hpp delete mode 100644 modules/codec-minecraft/var_int_data.h create mode 100644 modules/codec-minecraft/var_int_data.hpp delete mode 100644 modules/codec-netcdf/c++/netcdf.h create mode 100644 modules/codec-netcdf/c++/netcdf.hpp delete mode 100644 modules/codec-netcdf/c++/netcdf.tmpl.h create mode 100644 modules/codec-netcdf/c++/netcdf.tmpl.hpp delete mode 100644 modules/codec/c++/args.h create mode 100644 modules/codec/c++/args.hpp delete mode 100644 modules/codec/c++/crc32.h create mode 100644 modules/codec/c++/crc32.hpp delete mode 100644 modules/codec/c++/csv.h create mode 100644 modules/codec/c++/csv.hpp delete mode 100644 modules/codec/c++/data.h create mode 100644 modules/codec/c++/data.hpp delete mode 100644 modules/codec/c++/forst.h create mode 100644 modules/codec/c++/forst.hpp delete mode 100644 modules/codec/c++/forst.tmpl.h create mode 100644 modules/codec/c++/forst.tmpl.hpp delete mode 100644 modules/codec/c++/interface.h create mode 100644 modules/codec/c++/interface.hpp delete mode 100644 modules/codec/c++/rpc.h create mode 100644 modules/codec/c++/rpc.hpp delete mode 100644 modules/codec/c++/schema.h create mode 100644 modules/codec/c++/schema.hpp delete mode 100644 modules/codec/c++/schema_factory.h create mode 100644 modules/codec/c++/schema_factory.hpp delete mode 100644 modules/codec/c++/schema_hash.h create mode 100644 modules/codec/c++/schema_hash.hpp delete mode 100644 modules/codec/c++/schema_stringify.h create mode 100644 modules/codec/c++/schema_stringify.hpp delete mode 100644 modules/codec/c++/simple.h create mode 100644 modules/codec/c++/simple.hpp delete mode 100644 modules/codec/c++/stream_value.h create mode 100644 modules/codec/c++/stream_value.hpp delete mode 100644 modules/core/c++/test/suite.h create mode 100644 modules/core/c++/test/suite.hpp delete mode 100644 modules/device-hip/c++/rpc.h create mode 100644 modules/device-hip/c++/rpc.hpp delete mode 100644 modules/io-tls/tls.h create mode 100644 modules/io-tls/tls.hpp delete mode 100644 modules/io/io.h create mode 100644 modules/io/io.hpp delete mode 100644 modules/io/io_helpers.h create mode 100644 modules/io/io_helpers.hpp delete mode 100644 modules/io_codec/io_peer.h create mode 100644 modules/io_codec/io_peer.hpp delete mode 100644 modules/io_codec/io_peer.tmpl.h create mode 100644 modules/io_codec/io_peer.tmpl.hpp delete mode 100644 modules/io_codec/rpc.h create mode 100644 modules/io_codec/rpc.hpp delete mode 100644 modules/window-opengl/gl_backends.h create mode 100644 modules/window-opengl/gl_backends.hpp delete mode 100644 modules/window-opengl/gl_context.h create mode 100644 modules/window-opengl/gl_context.hpp delete mode 100644 modules/window-opengl/gl_window.h create mode 100644 modules/window-opengl/gl_window.hpp delete mode 100644 modules/window-opengl/gl_xcb.h create mode 100644 modules/window-opengl/gl_xcb.hpp delete mode 100644 modules/window/c++/backends.h create mode 100644 modules/window/c++/backends.hpp delete mode 100644 modules/window/c++/device.h create mode 100644 modules/window/c++/device.hpp delete mode 100644 modules/window/c++/linux_xcb.h create mode 100644 modules/window/c++/linux_xcb.hpp delete mode 100644 modules/window/c++/video_mode.h create mode 100644 modules/window/c++/video_mode.hpp delete mode 100644 modules/window/c++/window.h create mode 100644 modules/window/c++/window.hpp delete mode 100644 modules/window/c++/xcb.h create mode 100644 modules/window/c++/xcb.hpp (limited to 'modules') diff --git a/modules/codec-json/c++/json.h b/modules/codec-json/c++/json.h deleted file mode 100644 index bc60ee9..0000000 --- a/modules/codec-json/c++/json.h +++ /dev/null @@ -1,120 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -namespace saw { -namespace encode { -struct Json {}; -} - -template -class data { -private: - ring_buffer buffer_; -public: - data():buffer_{}{} - - data(std::size_t ring_size_):buffer_{ring_size_}{} - - data(ring_buffer buff_): - buffer_{std::move(buff_)} - {} - - data(const std::string_view& view__): - buffer_{view__.size()} - { - auto ptr = reinterpret_cast(view__.data()); - if(!ptr){ - return; - } - buffer_.push(*ptr, view__.size()); - } - - buffer& get_buffer(){ - return buffer_; - } - - const buffer& get_buffer() const { - return buffer_; - } - - error push(uint8_t val){ - return buffer_.push(val); - } - - std::size_t get_size() const { - return buffer_.read_composite_length(); - } - - uint8_t& at(std::size_t i){ - return buffer_.read(i); - } - - const uint8_t& at(std::size_t i) const { - return buffer_.read(i); - } -}; -} - -#include "json.tmpl.h" - -namespace saw { - -/** - * Codec class for json - */ -template -class codec { -public: - struct config { - size_t depth = 16; - size_t length = 1024; - }; -private: - config cfg_; -public: - /** - * Default constructor - */ - codec(){} - - /** - * Constructor - */ - codec(config cfg__):cfg_{std::move(cfg__)}{} - - SAW_FORBID_COPY(codec); - SAW_DEFAULT_MOVE(codec); - - template - error_or encode(const data& from_encode, data& to_encode){ - // To Be encoded - buffer_view buff_v{to_encode.get_buffer()}; - auto eov = impl::json_encode::encode(from_encode, buff_v); - if(eov.is_error()){ - return std::move(eov.get_error()); - } - to_encode.get_buffer().write_advance(buff_v.write_offset()); - - return void_t{}; - } - - template - error_or decode(data& from_decode, data& to_decode){ - buffer_view buff_v{from_decode.get_buffer()}; - - auto eov = impl::json_decode::decode(buff_v, to_decode); - if(eov.is_error()){ - return std::move(eov.get_error()); - } - from_decode.get_buffer().read_advance(buff_v.read_offset()); - - return void_t {}; - } -}; -} - diff --git a/modules/codec-json/c++/json.hpp b/modules/codec-json/c++/json.hpp new file mode 100644 index 0000000..d81a508 --- /dev/null +++ b/modules/codec-json/c++/json.hpp @@ -0,0 +1,120 @@ +#pragma once + +#include +#include +#include + +#include + +namespace saw { +namespace encode { +struct Json {}; +} + +template +class data { +private: + ring_buffer buffer_; +public: + data():buffer_{}{} + + data(std::size_t ring_size_):buffer_{ring_size_}{} + + data(ring_buffer buff_): + buffer_{std::move(buff_)} + {} + + data(const std::string_view& view__): + buffer_{view__.size()} + { + auto ptr = reinterpret_cast(view__.data()); + if(!ptr){ + return; + } + buffer_.push(*ptr, view__.size()); + } + + buffer& get_buffer(){ + return buffer_; + } + + const buffer& get_buffer() const { + return buffer_; + } + + error push(uint8_t val){ + return buffer_.push(val); + } + + std::size_t get_size() const { + return buffer_.read_composite_length(); + } + + uint8_t& at(std::size_t i){ + return buffer_.read(i); + } + + const uint8_t& at(std::size_t i) const { + return buffer_.read(i); + } +}; +} + +#include "json.tmpl.hpp + +namespace saw { + +/** + * Codec class for json + */ +template +class codec { +public: + struct config { + size_t depth = 16; + size_t length = 1024; + }; +private: + config cfg_; +public: + /** + * Default constructor + */ + codec(){} + + /** + * Constructor + */ + codec(config cfg__):cfg_{std::move(cfg__)}{} + + SAW_FORBID_COPY(codec); + SAW_DEFAULT_MOVE(codec); + + template + error_or encode(const data& from_encode, data& to_encode){ + // To Be encoded + buffer_view buff_v{to_encode.get_buffer()}; + auto eov = impl::json_encode::encode(from_encode, buff_v); + if(eov.is_error()){ + return std::move(eov.get_error()); + } + to_encode.get_buffer().write_advance(buff_v.write_offset()); + + return void_t{}; + } + + template + error_or decode(data& from_decode, data& to_decode){ + buffer_view buff_v{from_decode.get_buffer()}; + + auto eov = impl::json_decode::decode(buff_v, to_decode); + if(eov.is_error()){ + return std::move(eov.get_error()); + } + from_decode.get_buffer().read_advance(buff_v.read_offset()); + + return void_t {}; + } +}; +} + diff --git a/modules/codec-json/c++/json.tmpl.h b/modules/codec-json/c++/json.tmpl.h deleted file mode 100644 index 84f0058..0000000 --- a/modules/codec-json/c++/json.tmpl.h +++ /dev/null @@ -1,734 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace saw { -namespace impl { -template -class json_encode { - static_assert(always_false, "This schema type is not being handled by the json encoding."); -}; - -template -struct json_encode, RootSchema, FromEncode> { - static error_or encode(const data, FromEncode>& from, buffer& to) { - auto val = from.get(); - std::array data; - auto tc_result = std::to_chars(reinterpret_cast(data.data()), reinterpret_cast(data.data())+data.size(), val); - - if(tc_result.ec != std::errc{}){ - return make_error(); - } - - size_t bytes_written = 0; - for(char* ptr = reinterpret_cast(data.data()); ptr != tc_result.ptr; ++ptr){ - ++bytes_written; - } - - auto& buff = to; - error err = buff.write_require_length(bytes_written); - if(!err.template is_type()){ - return std::move(err); - } - - for(char* ptr = reinterpret_cast(data.data()); ptr != tc_result.ptr; ++ptr){ - uint8_t* un_ptr = reinterpret_cast(ptr); - buff.push(un_ptr[0]); - } - - return void_t{}; - } -}; - -template -struct json_encode { - static error_or encode(const data& from, buffer& to) { - { - auto err = to.push('"'); - if(!err.template is_type()){ - return err; - } - } - for(std::size_t i = 0; i < from.size(); ++i){ - auto err = to.push(from.get_at(i)); - if(!err.template is_type()){ - return err; - } - } - { - auto err = to.push('"'); - if(!err.template is_type()){ - return err; - } - } - - return void_t{}; - } -}; - -template -struct json_encode, RootSchema, FromEncode> { - template - static error_or encode_element(const data, FromEncode>& from, buffer& to){ - auto eov = json_encode::type, RootSchema, FromEncode>::encode(from.template get(), to); - - if(eov.is_error()){ - return eov; - } - - if constexpr ( (i+1) < sizeof...(T)){ - { - auto eov_ele = to.push(','); - if(!eov_ele.template is_type()){ - return eov_ele; - } - } - { - auto eov_ele = encode_element(from, to); - if(eov_ele.is_error()){ - return eov_ele; - } - } - - - } - return void_t{}; - } - - static error_or encode(const data, FromEncode>& from, buffer& to) { - { - auto err = to.push('['); - if(!err.template is_type()){ - return err; - } - } - if constexpr ( sizeof...(T) > 0 ){ - auto eov = encode_element<0>(from, to); - if(eov.is_error()){ - return eov; - } - } - { - auto err = to.push(']'); - if(!err.template is_type()){ - return err; - } - } - - return void_t{}; - } -}; - -template -struct json_encode, RootSchema, FromEncode> { - template - static error_or encode_level(const data, FromEncode>& from, buffer& to, std::array& index){ - if constexpr (Level == D){ - auto eov = json_encode::encode(from.at(index), to); - if(eov.is_error()){ - return eov; - } - } else { - { - auto err = to.push('['); - if(!err.template is_type()){ - return err; - } - } - for(std::size_t i = 0; i < from.get_dim_size(Level); ++i){ - if( i > 0 ){ - auto err = to.push(','); - if(!err.template is_type()){ - return err; - } - } - { - index[Level] = i; - auto eov = encode_level(from, to, index); - if(eov.is_error()){ - return eov; - } - } - } - { - auto err = to.push(']'); - if(!err.template is_type()){ - return err; - } - } - } - return void_t{}; - } - - static error_or encode(const data, FromEncode>& from, buffer& to) { - std::array index; - return encode_level<0>(from, to, index); - } -}; - -template -struct json_encode...>, RootSchema, FromEncode> { - - template - static error_or encode_element(const data...>, FromEncode>& from, buffer& to){ - // Encode the name - { - std::string_view view = parameter_key_pack_type::literal.view(); - error err = to.push('"'); - if(!err.template is_type()){ - return err; - } - err = to.push(*reinterpret_cast(view.data()), view.size()); - if(!err.template is_type()){ - return err; - } - err = to.push('"'); - if(!err.template is_type()){ - return err; - } - } - // Add the separator - { - auto eov_ele = to.push(':'); - if(!eov_ele.template is_type()){ - return eov_ele; - } - } - - // Encode the value - auto eov = json_encode::type, RootSchema, FromEncode>::encode(from.template get::literal>(), to); - - // Go to the next element - if constexpr ( (i+1) < sizeof...(T)){ - { - auto eov_ele = to.push(','); - if(!eov_ele.template is_type()){ - return eov_ele; - } - } - { - auto eov_ele = encode_element(from, to); - if(eov_ele.is_error()){ - return eov_ele; - } - } - - - } - - return void_t{}; - } - static error_or encode(const data...>, FromEncode>& from, buffer& to) { - { - auto err = to.push('{'); - if(!err.template is_type()){ - return err; - } - } - if constexpr ( sizeof...(T) > 0 ){ - auto eov = encode_element<0>(from, to); - if(eov.is_error()){ - return eov; - } - } - { - auto err = to.push('}'); - if(!err.template is_type()){ - return err; - } - } - - return void_t{}; - } -}; - -template -struct json_encode...>, RootSchema, FromEncode> { - - template - static error_or encode_element(const data...>, FromEncode>& from, buffer& to){ - if(from.template holds_alternative::literal>()){ - // Encode the name - { - std::string_view view = parameter_key_pack_type::literal.view(); - error err = to.push('"'); - if(!err.template is_type()){ - return err; - } - err = to.push(*reinterpret_cast(view.data()), view.size()); - if(!err.template is_type()){ - return err; - } - err = to.push('"'); - if(!err.template is_type()){ - return err; - } - } - // Add the separator - { - auto eov_ele = to.push(':'); - if(!eov_ele.template is_type()){ - return eov_ele; - } - } - - // Encode the value - auto eov = json_encode::type, RootSchema, FromEncode>::encode(from.template get::literal>(), to); - } - // Go to the next element - if constexpr ( (i+1) < sizeof...(T)){ - { - auto eov_ele = encode_element(from, to); - if(eov_ele.is_error()){ - return eov_ele; - } - } - - - } - - return void_t{}; - } - static error_or encode(const data...>, FromEncode>& from, buffer& to) { - { - auto err = to.push('{'); - if(!err.template is_type()){ - return err; - } - } - if constexpr ( sizeof...(T) > 0 ){ - auto eov = encode_element<0>(from, to); - if(eov.is_error()){ - return eov; - } - } - { - auto err = to.push('}'); - if(!err.template is_type()){ - return err; - } - } - - return void_t{}; - } -}; - -struct json_helper { - static bool is_whitespace(int8_t ch) { - return ch == '\t' || ch == ' ' || ch == '\r' || ch == '\n'; - } - - static void skip_whitespace(buffer_view& buff) { - while(buff.read_composite_length() > 0 && json_helper::is_whitespace(buff.read())) { - buff.read_advance(1); - } - } -}; - -template -struct json_decode; - -template -struct json_decode, RootSchema, ToDecode> { - static error_or decode(buffer_view& buff, data, ToDecode>& to) { - assert( - ( buff.read() >= '0' && buff.read() <= '9') - || ( buff.read() == '+' || buff.read() == '-') - ); - - std::size_t offset = 0; - - if (buff.read() == '-'){ - ++offset; - } else if (buff.read() == '+'){ - return make_error(); - } - if (offset >= buff.read_composite_length()) { - return make_error(); - } - if (buff.read(offset) >= '1' && buff.read(offset) <= '9') { - ++offset; - - if(offset >= buff.read_composite_length()) { - return make_error(); - } - - while(1){ - if (buff.read(offset) >= '0' && buff.read(offset) <= '9') { - ++offset; - - if(offset >= buff.read_composite_length()) { - break; - } - continue; - } - break; - } - } else if (buff.read(offset) == '0' ) { - ++offset; - } else { - return make_error(); - } - - { - std::string_view num_view{reinterpret_cast(&buff.read()), offset}; - typename native_data_type>::type result; - auto fc_result = std::from_chars(num_view.data(), num_view.data() + num_view.size(), result); - if(fc_result.ec != std::errc{}){ - return make_error(); - } - - to.set(result); - } - buff.read_advance(offset); - - return void_t{}; - } -}; - -template -struct json_decode { - static error_or decode(buffer_view& buff, data& to){ - assert(buff.read() == '"'); - buff.read_advance(1); - - std::stringstream iss; - bool string_done = false; - while(!string_done){ - if(buff.read_composite_length() == 0){ - return make_error(); - } - - switch(buff.read()){ - case '\\':{ - buff.read_advance(1); - if(buff.read_composite_length() == 0){ - return make_error(); - } - switch(buff.read()){ - case '\\': - case '/': - case '"': - iss<< buff.read(); - break; - case 'b': - iss<<'\b'; - break; - case 'f': - iss<<'\f'; - break; - case 'n': - iss<<'\n'; - break; - case 'r': - iss<<'\r'; - break; - case 't': - iss<<'\t'; - break; - case 'u': { - buff.read_advance(1); - if(buff.read_composite_length() < 4){ - return make_error(); - } - iss<<'?'; - iss<<'?'; - iss<<'?'; - iss<<'?'; - - buff.read_advance(3); - } break; - } - } break; - case '"': - string_done = true; - break; - default:{ - // Avoids Control sequences - if(buff.read() >= ' ' && buff.read() <= '~'){ - iss<(); - } - } while( buff.read() < 0 ); - iss<<'?'; - } - break; - } - } - buff.read_advance(1); - } - - std::string raw = iss.str(); - to.set(std::move(raw)); - - return void_t{}; - } -}; - -template -struct json_decode...>, RootSchema, ToDecode> { - template - static error_or decode_field_search(buffer_view& buff, data...>, ToDecode>& to, std::array& fields, const data& search_name){ - if constexpr ( i < sizeof...(T)){ - using Type = typename parameter_pack_type::type; - constexpr static string_literal Literal = parameter_key_pack_type::literal; - if(search_name == Literal.view()){ - if(fields[i]){ - return make_error(); - } - fields[i] = true; - auto eov = json_decode::decode(buff, to.template get()); - if(eov.is_error()){ - return eov; - } - }else { - decode_field_search(buff, to, fields, search_name); - } - }else { - return make_error(); - } - return void_t{}; - } - - static error_or decode_fields(buffer_view& buff, data...>, ToDecode>& to, std::array& fields){ - for(;;){ - data name; - auto eov = json_decode::decode(buff, name); - if(eov.is_error()){ - return eov; - } - json_helper::skip_whitespace(buff); - if(buff.read_composite_length() == 0){ - return make_error(); - } - if(buff.read() != ':'){ - return make_error(); - } - buff.read_advance(1); - json_helper::skip_whitespace(buff); - if(buff.read_composite_length() == 0){ - return make_error(); - } - { - auto eov = decode_field_search<0>(buff, to, fields, name); - if(eov.is_error()){ - return eov; - } - } - json_helper::skip_whitespace(buff); - if(buff.read_composite_length() == 0){ - return make_error(); - } - if(buff.read() == ','){ - buff.read_advance(1); - }else if(buff.read() == '}'){ - // If not all fields are set, the dataset is incomplete - for(auto& iter : fields){ - if(!iter){ - return make_error(); - } - } - buff.read_advance(1); - return void_t{}; - }else{ - return make_error(); - } - json_helper::skip_whitespace(buff); - if(buff.read_composite_length() == 0){ - return make_error(); - } - } - return void_t{}; - } - - static error_or decode(buffer_view& buff, data...>, ToDecode>& to){ - std::array found_fields; - std::fill(found_fields.begin(), found_fields.end(), false); - - assert(buff.read() == '{'); - buff.read_advance(1); - json_helper::skip_whitespace(buff); - if(buff.read_composite_length() == 0){ - return make_error(); - } - - // Check if there are no elements present in the JSON Struct - if(buff.read() == '}'){ - if(sizeof...(T) > 0){ - return make_error(); - } - buff.read_advance(1); - return void_t{}; - } - - auto eov = decode_fields(buff, to, found_fields); - if(eov.is_error()){ - return eov; - } - - return void_t{}; - } -}; - -template -struct json_decode, RootSchema, ToDecode> { - template - static error_or decode_element(buffer_view& buff, data, ToDecode>& to){ - if constexpr (i < sizeof...(T)){ - if constexpr ( i > 0 ){ - if(buff.read() != ','){ - return make_error(); - } - buff.read_advance(1); - if(buff.read_composite_length() == 0){ - return make_error(); - } - } - using Type = typename parameter_pack_type::type; - - auto eov = json_decode::decode(buff, to.template get()); - if(eov.is_error()){ - return eov; - } - json_helper::skip_whitespace(buff); - if(buff.read_composite_length() == 0){ - return make_error(); - } - - eov = decode_element(buff, to); - if(eov.is_error()){ - return eov; - } - }else{ - if(buff.read() != ']'){ - return make_error(); - } - buff.read_advance(1); - } - return void_t{}; - } - - static error_or decode(buffer_view& buff, data, ToDecode>& to){ - assert(buff.read() == '['); - buff.read_advance(1); - - json_helper::skip_whitespace(buff); - if(buff.read_composite_length() == 0){ - return make_error(); - } - - auto eov = decode_element<0>(buff, to); - if(eov.is_error()){ - return eov; - } - - return void_t{}; - } -}; - -// The whole std::vector approach is hacky af. ToDo change it maybe? -template -struct json_decode, RootSchema, ToDecode> { - template - static error_or decode_flat_level(buffer_view& buff, std::vector>& to, std::array& index, std::array& dims, bool log_dim){ - if constexpr (Level == D) { - json_helper::skip_whitespace(buff); - try { - to.push_back({}); - }catch(std::exception& e){ - return make_error(); - } - auto eov = json_decode::decode(buff, to.back()); - if(eov.is_error()){ - return eov; - } - } else { - assert(buff.read() == '['); - buff.read_advance(1); - - json_helper::skip_whitespace(buff); - if ( buff.read_composite_length() == 0 ){ - return make_error(); - } - - index[Level] = 0; - for(;;){ - // We should have an element right now - auto eov = decode_flat_level(buff,to,index,dims, index[Level] == 0 && log_dim); - if(eov.is_error()){ - return eov; - } - json_helper::skip_whitespace(buff); - if ( buff.read_composite_length() == 0 ){ - return make_error(); - } - - ++index[Level]; - if(buff.read() == ','){ - buff.read_advance(1); - } else if(buff.read() == ']'){ - buff.read_advance(1); - break; - } else { - return make_error(); - } - json_helper::skip_whitespace(buff); - if ( buff.read_composite_length() == 0 ){ - return make_error(); - } - } - if(log_dim){ - dims[Level] = index[Level]; - }else if (dims[Level] != index[Level]){ - return make_error(); - } - } - return void_t{}; - } - - template - static error_or decode_unflat_level(std::vector>& flat, data, ToDecode>& to, std::array& index, std::size_t& flat_index) { - if constexpr ( Level == D ){ - auto& flat_data = flat.at(flat_index); - to.at(index) = std::move(flat_data); - ++flat_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_unflat_level(flat, to, index, flat_index); - if(eov.is_error()){ - return eov; - } - } - } - return void_t{}; - } - - static error_or decode(buffer_view& buff, data, ToDecode>& to){ - std::array index; - std::array dims; - std::fill(dims.begin(), dims.end(), 0); - std::vector> flat_array; - auto eov = decode_flat_level<0>(buff, flat_array, index, dims, true); - if(eov.is_error()){ - return eov; - } - - to = {dims}; - std::size_t flat_index = 0; - - return decode_unflat_level<0>(flat_array, to, index, flat_index); - } -}; -} -} diff --git a/modules/codec-json/c++/json.tmpl.hpp b/modules/codec-json/c++/json.tmpl.hpp new file mode 100644 index 0000000..84f0058 --- /dev/null +++ b/modules/codec-json/c++/json.tmpl.hpp @@ -0,0 +1,734 @@ +#pragma once + +#include +#include + +#include + +namespace saw { +namespace impl { +template +class json_encode { + static_assert(always_false, "This schema type is not being handled by the json encoding."); +}; + +template +struct json_encode, RootSchema, FromEncode> { + static error_or encode(const data, FromEncode>& from, buffer& to) { + auto val = from.get(); + std::array data; + auto tc_result = std::to_chars(reinterpret_cast(data.data()), reinterpret_cast(data.data())+data.size(), val); + + if(tc_result.ec != std::errc{}){ + return make_error(); + } + + size_t bytes_written = 0; + for(char* ptr = reinterpret_cast(data.data()); ptr != tc_result.ptr; ++ptr){ + ++bytes_written; + } + + auto& buff = to; + error err = buff.write_require_length(bytes_written); + if(!err.template is_type()){ + return std::move(err); + } + + for(char* ptr = reinterpret_cast(data.data()); ptr != tc_result.ptr; ++ptr){ + uint8_t* un_ptr = reinterpret_cast(ptr); + buff.push(un_ptr[0]); + } + + return void_t{}; + } +}; + +template +struct json_encode { + static error_or encode(const data& from, buffer& to) { + { + auto err = to.push('"'); + if(!err.template is_type()){ + return err; + } + } + for(std::size_t i = 0; i < from.size(); ++i){ + auto err = to.push(from.get_at(i)); + if(!err.template is_type()){ + return err; + } + } + { + auto err = to.push('"'); + if(!err.template is_type()){ + return err; + } + } + + return void_t{}; + } +}; + +template +struct json_encode, RootSchema, FromEncode> { + template + static error_or encode_element(const data, FromEncode>& from, buffer& to){ + auto eov = json_encode::type, RootSchema, FromEncode>::encode(from.template get(), to); + + if(eov.is_error()){ + return eov; + } + + if constexpr ( (i+1) < sizeof...(T)){ + { + auto eov_ele = to.push(','); + if(!eov_ele.template is_type()){ + return eov_ele; + } + } + { + auto eov_ele = encode_element(from, to); + if(eov_ele.is_error()){ + return eov_ele; + } + } + + + } + return void_t{}; + } + + static error_or encode(const data, FromEncode>& from, buffer& to) { + { + auto err = to.push('['); + if(!err.template is_type()){ + return err; + } + } + if constexpr ( sizeof...(T) > 0 ){ + auto eov = encode_element<0>(from, to); + if(eov.is_error()){ + return eov; + } + } + { + auto err = to.push(']'); + if(!err.template is_type()){ + return err; + } + } + + return void_t{}; + } +}; + +template +struct json_encode, RootSchema, FromEncode> { + template + static error_or encode_level(const data, FromEncode>& from, buffer& to, std::array& index){ + if constexpr (Level == D){ + auto eov = json_encode::encode(from.at(index), to); + if(eov.is_error()){ + return eov; + } + } else { + { + auto err = to.push('['); + if(!err.template is_type()){ + return err; + } + } + for(std::size_t i = 0; i < from.get_dim_size(Level); ++i){ + if( i > 0 ){ + auto err = to.push(','); + if(!err.template is_type()){ + return err; + } + } + { + index[Level] = i; + auto eov = encode_level(from, to, index); + if(eov.is_error()){ + return eov; + } + } + } + { + auto err = to.push(']'); + if(!err.template is_type()){ + return err; + } + } + } + return void_t{}; + } + + static error_or encode(const data, FromEncode>& from, buffer& to) { + std::array index; + return encode_level<0>(from, to, index); + } +}; + +template +struct json_encode...>, RootSchema, FromEncode> { + + template + static error_or encode_element(const data...>, FromEncode>& from, buffer& to){ + // Encode the name + { + std::string_view view = parameter_key_pack_type::literal.view(); + error err = to.push('"'); + if(!err.template is_type()){ + return err; + } + err = to.push(*reinterpret_cast(view.data()), view.size()); + if(!err.template is_type()){ + return err; + } + err = to.push('"'); + if(!err.template is_type()){ + return err; + } + } + // Add the separator + { + auto eov_ele = to.push(':'); + if(!eov_ele.template is_type()){ + return eov_ele; + } + } + + // Encode the value + auto eov = json_encode::type, RootSchema, FromEncode>::encode(from.template get::literal>(), to); + + // Go to the next element + if constexpr ( (i+1) < sizeof...(T)){ + { + auto eov_ele = to.push(','); + if(!eov_ele.template is_type()){ + return eov_ele; + } + } + { + auto eov_ele = encode_element(from, to); + if(eov_ele.is_error()){ + return eov_ele; + } + } + + + } + + return void_t{}; + } + static error_or encode(const data...>, FromEncode>& from, buffer& to) { + { + auto err = to.push('{'); + if(!err.template is_type()){ + return err; + } + } + if constexpr ( sizeof...(T) > 0 ){ + auto eov = encode_element<0>(from, to); + if(eov.is_error()){ + return eov; + } + } + { + auto err = to.push('}'); + if(!err.template is_type()){ + return err; + } + } + + return void_t{}; + } +}; + +template +struct json_encode...>, RootSchema, FromEncode> { + + template + static error_or encode_element(const data...>, FromEncode>& from, buffer& to){ + if(from.template holds_alternative::literal>()){ + // Encode the name + { + std::string_view view = parameter_key_pack_type::literal.view(); + error err = to.push('"'); + if(!err.template is_type()){ + return err; + } + err = to.push(*reinterpret_cast(view.data()), view.size()); + if(!err.template is_type()){ + return err; + } + err = to.push('"'); + if(!err.template is_type()){ + return err; + } + } + // Add the separator + { + auto eov_ele = to.push(':'); + if(!eov_ele.template is_type()){ + return eov_ele; + } + } + + // Encode the value + auto eov = json_encode::type, RootSchema, FromEncode>::encode(from.template get::literal>(), to); + } + // Go to the next element + if constexpr ( (i+1) < sizeof...(T)){ + { + auto eov_ele = encode_element(from, to); + if(eov_ele.is_error()){ + return eov_ele; + } + } + + + } + + return void_t{}; + } + static error_or encode(const data...>, FromEncode>& from, buffer& to) { + { + auto err = to.push('{'); + if(!err.template is_type()){ + return err; + } + } + if constexpr ( sizeof...(T) > 0 ){ + auto eov = encode_element<0>(from, to); + if(eov.is_error()){ + return eov; + } + } + { + auto err = to.push('}'); + if(!err.template is_type()){ + return err; + } + } + + return void_t{}; + } +}; + +struct json_helper { + static bool is_whitespace(int8_t ch) { + return ch == '\t' || ch == ' ' || ch == '\r' || ch == '\n'; + } + + static void skip_whitespace(buffer_view& buff) { + while(buff.read_composite_length() > 0 && json_helper::is_whitespace(buff.read())) { + buff.read_advance(1); + } + } +}; + +template +struct json_decode; + +template +struct json_decode, RootSchema, ToDecode> { + static error_or decode(buffer_view& buff, data, ToDecode>& to) { + assert( + ( buff.read() >= '0' && buff.read() <= '9') + || ( buff.read() == '+' || buff.read() == '-') + ); + + std::size_t offset = 0; + + if (buff.read() == '-'){ + ++offset; + } else if (buff.read() == '+'){ + return make_error(); + } + if (offset >= buff.read_composite_length()) { + return make_error(); + } + if (buff.read(offset) >= '1' && buff.read(offset) <= '9') { + ++offset; + + if(offset >= buff.read_composite_length()) { + return make_error(); + } + + while(1){ + if (buff.read(offset) >= '0' && buff.read(offset) <= '9') { + ++offset; + + if(offset >= buff.read_composite_length()) { + break; + } + continue; + } + break; + } + } else if (buff.read(offset) == '0' ) { + ++offset; + } else { + return make_error(); + } + + { + std::string_view num_view{reinterpret_cast(&buff.read()), offset}; + typename native_data_type>::type result; + auto fc_result = std::from_chars(num_view.data(), num_view.data() + num_view.size(), result); + if(fc_result.ec != std::errc{}){ + return make_error(); + } + + to.set(result); + } + buff.read_advance(offset); + + return void_t{}; + } +}; + +template +struct json_decode { + static error_or decode(buffer_view& buff, data& to){ + assert(buff.read() == '"'); + buff.read_advance(1); + + std::stringstream iss; + bool string_done = false; + while(!string_done){ + if(buff.read_composite_length() == 0){ + return make_error(); + } + + switch(buff.read()){ + case '\\':{ + buff.read_advance(1); + if(buff.read_composite_length() == 0){ + return make_error(); + } + switch(buff.read()){ + case '\\': + case '/': + case '"': + iss<< buff.read(); + break; + case 'b': + iss<<'\b'; + break; + case 'f': + iss<<'\f'; + break; + case 'n': + iss<<'\n'; + break; + case 'r': + iss<<'\r'; + break; + case 't': + iss<<'\t'; + break; + case 'u': { + buff.read_advance(1); + if(buff.read_composite_length() < 4){ + return make_error(); + } + iss<<'?'; + iss<<'?'; + iss<<'?'; + iss<<'?'; + + buff.read_advance(3); + } break; + } + } break; + case '"': + string_done = true; + break; + default:{ + // Avoids Control sequences + if(buff.read() >= ' ' && buff.read() <= '~'){ + iss<(); + } + } while( buff.read() < 0 ); + iss<<'?'; + } + break; + } + } + buff.read_advance(1); + } + + std::string raw = iss.str(); + to.set(std::move(raw)); + + return void_t{}; + } +}; + +template +struct json_decode...>, RootSchema, ToDecode> { + template + static error_or decode_field_search(buffer_view& buff, data...>, ToDecode>& to, std::array& fields, const data& search_name){ + if constexpr ( i < sizeof...(T)){ + using Type = typename parameter_pack_type::type; + constexpr static string_literal Literal = parameter_key_pack_type::literal; + if(search_name == Literal.view()){ + if(fields[i]){ + return make_error(); + } + fields[i] = true; + auto eov = json_decode::decode(buff, to.template get()); + if(eov.is_error()){ + return eov; + } + }else { + decode_field_search(buff, to, fields, search_name); + } + }else { + return make_error(); + } + return void_t{}; + } + + static error_or decode_fields(buffer_view& buff, data...>, ToDecode>& to, std::array& fields){ + for(;;){ + data name; + auto eov = json_decode::decode(buff, name); + if(eov.is_error()){ + return eov; + } + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + if(buff.read() != ':'){ + return make_error(); + } + buff.read_advance(1); + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + { + auto eov = decode_field_search<0>(buff, to, fields, name); + if(eov.is_error()){ + return eov; + } + } + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + if(buff.read() == ','){ + buff.read_advance(1); + }else if(buff.read() == '}'){ + // If not all fields are set, the dataset is incomplete + for(auto& iter : fields){ + if(!iter){ + return make_error(); + } + } + buff.read_advance(1); + return void_t{}; + }else{ + return make_error(); + } + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + } + return void_t{}; + } + + static error_or decode(buffer_view& buff, data...>, ToDecode>& to){ + std::array found_fields; + std::fill(found_fields.begin(), found_fields.end(), false); + + assert(buff.read() == '{'); + buff.read_advance(1); + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + + // Check if there are no elements present in the JSON Struct + if(buff.read() == '}'){ + if(sizeof...(T) > 0){ + return make_error(); + } + buff.read_advance(1); + return void_t{}; + } + + auto eov = decode_fields(buff, to, found_fields); + if(eov.is_error()){ + return eov; + } + + return void_t{}; + } +}; + +template +struct json_decode, RootSchema, ToDecode> { + template + static error_or decode_element(buffer_view& buff, data, ToDecode>& to){ + if constexpr (i < sizeof...(T)){ + if constexpr ( i > 0 ){ + if(buff.read() != ','){ + return make_error(); + } + buff.read_advance(1); + if(buff.read_composite_length() == 0){ + return make_error(); + } + } + using Type = typename parameter_pack_type::type; + + auto eov = json_decode::decode(buff, to.template get()); + if(eov.is_error()){ + return eov; + } + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + + eov = decode_element(buff, to); + if(eov.is_error()){ + return eov; + } + }else{ + if(buff.read() != ']'){ + return make_error(); + } + buff.read_advance(1); + } + return void_t{}; + } + + static error_or decode(buffer_view& buff, data, ToDecode>& to){ + assert(buff.read() == '['); + buff.read_advance(1); + + json_helper::skip_whitespace(buff); + if(buff.read_composite_length() == 0){ + return make_error(); + } + + auto eov = decode_element<0>(buff, to); + if(eov.is_error()){ + return eov; + } + + return void_t{}; + } +}; + +// The whole std::vector approach is hacky af. ToDo change it maybe? +template +struct json_decode, RootSchema, ToDecode> { + template + static error_or decode_flat_level(buffer_view& buff, std::vector>& to, std::array& index, std::array& dims, bool log_dim){ + if constexpr (Level == D) { + json_helper::skip_whitespace(buff); + try { + to.push_back({}); + }catch(std::exception& e){ + return make_error(); + } + auto eov = json_decode::decode(buff, to.back()); + if(eov.is_error()){ + return eov; + } + } else { + assert(buff.read() == '['); + buff.read_advance(1); + + json_helper::skip_whitespace(buff); + if ( buff.read_composite_length() == 0 ){ + return make_error(); + } + + index[Level] = 0; + for(;;){ + // We should have an element right now + auto eov = decode_flat_level(buff,to,index,dims, index[Level] == 0 && log_dim); + if(eov.is_error()){ + return eov; + } + json_helper::skip_whitespace(buff); + if ( buff.read_composite_length() == 0 ){ + return make_error(); + } + + ++index[Level]; + if(buff.read() == ','){ + buff.read_advance(1); + } else if(buff.read() == ']'){ + buff.read_advance(1); + break; + } else { + return make_error(); + } + json_helper::skip_whitespace(buff); + if ( buff.read_composite_length() == 0 ){ + return make_error(); + } + } + if(log_dim){ + dims[Level] = index[Level]; + }else if (dims[Level] != index[Level]){ + return make_error(); + } + } + return void_t{}; + } + + template + static error_or decode_unflat_level(std::vector>& flat, data, ToDecode>& to, std::array& index, std::size_t& flat_index) { + if constexpr ( Level == D ){ + auto& flat_data = flat.at(flat_index); + to.at(index) = std::move(flat_data); + ++flat_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_unflat_level(flat, to, index, flat_index); + if(eov.is_error()){ + return eov; + } + } + } + return void_t{}; + } + + static error_or decode(buffer_view& buff, data, ToDecode>& to){ + std::array index; + std::array dims; + std::fill(dims.begin(), dims.end(), 0); + std::vector> flat_array; + auto eov = decode_flat_level<0>(buff, flat_array, index, dims, true); + if(eov.is_error()){ + return eov; + } + + to = {dims}; + std::size_t flat_index = 0; + + return decode_unflat_level<0>(flat_array, to, index, flat_index); + } +}; +} +} diff --git a/modules/codec-minecraft/minecraft.h b/modules/codec-minecraft/minecraft.h deleted file mode 100644 index c54549e..0000000 --- a/modules/codec-minecraft/minecraft.h +++ /dev/null @@ -1,116 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace saw { -namespace encode { -struct Minecraft {}; -struct VarIntTransport {}; -} - -template -class data { -private: - ring_buffer buffer_; -public: - data() = default; - data(std::size_t size): - buffer_{size} - {} - - buffer& get_buffer(){ - return buffer_; - } -}; - -namespace mc { -namespace impl { -union minecraft_signed_four_conversion { - int32_t s; - uint32_t u; -}; - -union minecraft_signed_eight_conversion { - int64_t s; - uint64_t u; -}; - -template -class minecraft_encode { - static_assert(always_false, "This schema type is not being handled by the Minecraft encoding."); -}; - -template -class minecraft_encode{ - static error_or encode(const data& from, buffer& to){ - uint8_t encode_index = 0; - minecraft_signed_four_conversion value; - value.s = from.get(); - - /** - * VarInt max length is 5 bytes - */ - std::array encode_data; - - do { - uint8_t step = static_cast(value.u & 0x7F); - value.u = value.u >> 7; - if(value.u != 0){ - step |= 0x80; - } - encode_data[encode_index] = step; - ++encode_index; - }while(value.u != 0); - - auto err = buffer.push(encode_data[0], encode_index); - if (!err.template is_type()) { - return err; - } - - return no_error(); - } -}; - -template -class minecraft_decode { - static_assert(always_false, "This schema type is not being handled by the Minecraft encoding."); -}; - -template -class minecraft_decode{ - static error_or decode(buffer& from, data& to){ - uint8_t num_reads = 0; - - minecraft_signed_four_conversion value; - value.u = 0; - - uint8_t read{}; - do { - auto err = from.pop(read); - if( !err.template is_type() ){ - return err; - } - value.u |= ((read & 0x7F) << (7*num_reads)); - ++num_reads; - if(num_reads > 5){ - return make_error(); - } - } while( (read & 0x80) != 0); - - to.set(value.s); - - return no_error(); - } -}; - -} -} - - - -namespace mc { - -} -} diff --git a/modules/codec-minecraft/minecraft.hpp b/modules/codec-minecraft/minecraft.hpp new file mode 100644 index 0000000..c54549e --- /dev/null +++ b/modules/codec-minecraft/minecraft.hpp @@ -0,0 +1,116 @@ +#pragma once + +#include +#include +#include + +namespace saw { +namespace encode { +struct Minecraft {}; +struct VarIntTransport {}; +} + +template +class data { +private: + ring_buffer buffer_; +public: + data() = default; + data(std::size_t size): + buffer_{size} + {} + + buffer& get_buffer(){ + return buffer_; + } +}; + +namespace mc { +namespace impl { +union minecraft_signed_four_conversion { + int32_t s; + uint32_t u; +}; + +union minecraft_signed_eight_conversion { + int64_t s; + uint64_t u; +}; + +template +class minecraft_encode { + static_assert(always_false, "This schema type is not being handled by the Minecraft encoding."); +}; + +template +class minecraft_encode{ + static error_or encode(const data& from, buffer& to){ + uint8_t encode_index = 0; + minecraft_signed_four_conversion value; + value.s = from.get(); + + /** + * VarInt max length is 5 bytes + */ + std::array encode_data; + + do { + uint8_t step = static_cast(value.u & 0x7F); + value.u = value.u >> 7; + if(value.u != 0){ + step |= 0x80; + } + encode_data[encode_index] = step; + ++encode_index; + }while(value.u != 0); + + auto err = buffer.push(encode_data[0], encode_index); + if (!err.template is_type()) { + return err; + } + + return no_error(); + } +}; + +template +class minecraft_decode { + static_assert(always_false, "This schema type is not being handled by the Minecraft encoding."); +}; + +template +class minecraft_decode{ + static error_or decode(buffer& from, data& to){ + uint8_t num_reads = 0; + + minecraft_signed_four_conversion value; + value.u = 0; + + uint8_t read{}; + do { + auto err = from.pop(read); + if( !err.template is_type() ){ + return err; + } + value.u |= ((read & 0x7F) << (7*num_reads)); + ++num_reads; + if(num_reads > 5){ + return make_error(); + } + } while( (read & 0x80) != 0); + + to.set(value.s); + + return no_error(); + } +}; + +} +} + + + +namespace mc { + +} +} diff --git a/modules/codec-minecraft/var_int_data.h b/modules/codec-minecraft/var_int_data.h deleted file mode 100644 index 4fbdd57..0000000 --- a/modules/codec-minecraft/var_int_data.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include - -namespace saw { -template<> -class data { -private: - int32_t data_; -public: - data(); - data(int32_t data); - - int32_t get() const; - void set(int32_t); -}; - -template<> -class data { -private: - int64_t data_; -public: - data(); - data(int64_t data); - - int64_t get() const; - void set(int64_t); -}; - - -} diff --git a/modules/codec-minecraft/var_int_data.hpp b/modules/codec-minecraft/var_int_data.hpp new file mode 100644 index 0000000..4fbdd57 --- /dev/null +++ b/modules/codec-minecraft/var_int_data.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include + +namespace saw { +template<> +class data { +private: + int32_t data_; +public: + data(); + data(int32_t data); + + int32_t get() const; + void set(int32_t); +}; + +template<> +class data { +private: + int64_t data_; +public: + data(); + data(int64_t data); + + int64_t get() const; + void set(int64_t); +}; + + +} diff --git a/modules/codec-netcdf/c++/netcdf.h b/modules/codec-netcdf/c++/netcdf.h deleted file mode 100644 index 52ad494..0000000 --- a/modules/codec-netcdf/c++/netcdf.h +++ /dev/null @@ -1,151 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include - -namespace saw { -namespace encode { -/** - * Template type hint - */ -struct Netcdf {}; -} - -/** - * Class representing the files system netcdf file - */ -template -class data { -private: - std::vector buff_; -public: - data() = default; - - data(std::vector buff): - buff_{std::move(buff)} - {} - - template - data(const std::array& arr): - buff_{arr.begin(), arr.end()} - {} - - std::vector& get_data() { - return buff_; - } - - const std::vector& get_data() const { - return buff_; - } -}; - -template -class codec{ - static_assert(always_false, "NetCDF only supports Structs as a root object"); -}; - -} -#include "netcdf.tmpl.h" -namespace saw { - -template -class codec...>, encode::Netcdf> { -private: - using Schema = schema::Struct...>; -public: - SAW_FORBID_COPY(codec); - SAW_DEFAULT_MOVE(codec); - - /** - * Default constructor - */ - codec() = default; - - /** - * Encoder function - */ - template - error_or encode(const data& from, data& to) { - int rc{}; - int ncid{}; - - rc = nc_create_mem("forstio_internal_write_memory", 0,/*NC_NETCDF4, */0, &ncid); - if(rc != NC_NOERR){ - return make_error(); - } - - { - auto eov = impl::netcdf_encode::encode_meta(from, ncid); - if(eov.is_error()){ - nc_close(ncid); - return eov; - } - } - - rc = nc_enddef(ncid); - if(rc != NC_NOERR){ - nc_close(ncid); - return make_error(); - } - - { - auto eov = impl::netcdf_encode::encode(from, ncid); - if(eov.is_error()){ - nc_close(ncid); - return eov; - } - } - - NC_memio nc_memio; - rc = nc_close_memio(ncid, &nc_memio); - if(rc != NC_NOERR){ - return make_error(); - } - - if(!nc_memio.memory || nc_memio.size == 0){ - return make_error(); - } - - try { - to.get_data().resize(nc_memio.size); - }catch(const std::exception& e){ - (void) e; - return make_error(); - } - - for(std::size_t i = 0; i < nc_memio.size; ++i){ - to.get_data().at(i) = static_cast(nc_memio.memory)[i]; - } - - free(nc_memio.memory); - nc_memio.memory = nullptr; - - return void_t{}; - } - - /** - * Decoder function - */ - template - error_or decode(data& from_decode, data& to_decode) { - int ncid{}; - int rc{}; - - rc = nc_open_mem("forstio_internal_read_memory", NC_NOWRITE, from_decode.get_data().size(), &from_decode.get_data()[0], &ncid); - if(rc != NC_NOERR){ - // Don't know how to get the error, so fail critically. - return make_error(); - } - - auto eov = impl::netcdf_decode::decode(to_decode, ncid); - - nc_close(ncid); - - return eov; - } -}; -} diff --git a/modules/codec-netcdf/c++/netcdf.hpp b/modules/codec-netcdf/c++/netcdf.hpp new file mode 100644 index 0000000..66d6391 --- /dev/null +++ b/modules/codec-netcdf/c++/netcdf.hpp @@ -0,0 +1,151 @@ +#pragma once + +#include +#include +#include + +#include +#include + +namespace saw { +namespace encode { +/** + * Template type hint + */ +struct Netcdf {}; +} + +/** + * Class representing the files system netcdf file + */ +template +class data { +private: + std::vector buff_; +public: + data() = default; + + data(std::vector buff): + buff_{std::move(buff)} + {} + + template + data(const std::array& arr): + buff_{arr.begin(), arr.end()} + {} + + std::vector& get_data() { + return buff_; + } + + const std::vector& get_data() const { + return buff_; + } +}; + +template +class codec{ + static_assert(always_false, "NetCDF only supports Structs as a root object"); +}; + +} +#include "netcdf.tmpl.hpp +namespace saw { + +template +class codec...>, encode::Netcdf> { +private: + using Schema = schema::Struct...>; +public: + SAW_FORBID_COPY(codec); + SAW_DEFAULT_MOVE(codec); + + /** + * Default constructor + */ + codec() = default; + + /** + * Encoder function + */ + template + error_or encode(const data& from, data& to) { + int rc{}; + int ncid{}; + + rc = nc_create_mem("forstio_internal_write_memory", 0,/*NC_NETCDF4, */0, &ncid); + if(rc != NC_NOERR){ + return make_error(); + } + + { + auto eov = impl::netcdf_encode::encode_meta(from, ncid); + if(eov.is_error()){ + nc_close(ncid); + return eov; + } + } + + rc = nc_enddef(ncid); + if(rc != NC_NOERR){ + nc_close(ncid); + return make_error(); + } + + { + auto eov = impl::netcdf_encode::encode(from, ncid); + if(eov.is_error()){ + nc_close(ncid); + return eov; + } + } + + NC_memio nc_memio; + rc = nc_close_memio(ncid, &nc_memio); + if(rc != NC_NOERR){ + return make_error(); + } + + if(!nc_memio.memory || nc_memio.size == 0){ + return make_error(); + } + + try { + to.get_data().resize(nc_memio.size); + }catch(const std::exception& e){ + (void) e; + return make_error(); + } + + for(std::size_t i = 0; i < nc_memio.size; ++i){ + to.get_data().at(i) = static_cast(nc_memio.memory)[i]; + } + + free(nc_memio.memory); + nc_memio.memory = nullptr; + + return void_t{}; + } + + /** + * Decoder function + */ + template + error_or decode(data& from_decode, data& to_decode) { + int ncid{}; + int rc{}; + + rc = nc_open_mem("forstio_internal_read_memory", NC_NOWRITE, from_decode.get_data().size(), &from_decode.get_data()[0], &ncid); + if(rc != NC_NOERR){ + // Don't know how to get the error, so fail critically. + return make_error(); + } + + auto eov = impl::netcdf_decode::decode(to_decode, ncid); + + nc_close(ncid); + + return eov; + } +}; +} diff --git a/modules/codec-netcdf/c++/netcdf.tmpl.h b/modules/codec-netcdf/c++/netcdf.tmpl.h deleted file mode 100644 index bf257e4..0000000 --- a/modules/codec-netcdf/c++/netcdf.tmpl.h +++ /dev/null @@ -1,348 +0,0 @@ -#pragma once - -namespace saw { -namespace impl { -template -struct netcdf_primitive_id { - static_assert(always_false, "Not a primitive id"); -}; - -template<> -struct netcdf_primitive_id { - static constexpr nc_type value = NC_INT; -}; - -template<> -struct netcdf_primitive_id { - static constexpr nc_type value = NC_UINT; -}; - -template<> -struct netcdf_primitive_id { - static constexpr nc_type value = NC_INT64; -}; - -template<> -struct netcdf_primitive_id { - static constexpr nc_type value = NC_UINT64; -}; - -template<> -struct netcdf_primitive_id { - static constexpr nc_type value = NC_FLOAT; -}; - -template<> -struct netcdf_primitive_id { - static constexpr nc_type value = NC_DOUBLE; -}; - -template -struct netcdf_is_group { - static constexpr bool value = false; -}; - -template -struct netcdf_is_group...>> { - static constexpr bool value = true; -}; - -template -struct netcdf_encode; - -template -struct netcdf_encode, ToEncode> { - using Schema = schema::Primitive; - - static error_or encode(const data& from, int ncid, int ncvarid){ - int rc{}; - - typename native_data_type::type val = from.get(); - - rc = nc_put_var(ncid, ncvarid, &val); - if(rc != NC_NOERR) { - return make_error(); - } - - return void_t{}; - } - - static error_or encode_meta(const data& from, int ncid, int ncvarid){ - (void) from; - (void) ncid; - (void) ncvarid; - return void_t{}; - } -}; - -template -struct netcdf_encode, ToEncode> { - using Schema = schema::Array; - - template - static error_or encode_level(data& from, int ncid, int ncvarid){ - - return make_error(); - } - - static error_or encode(data& from, int ncid, int ncvarid){ - - return make_error(); - } - - static error_or encode_meta(const data& from, int ncid, int ncvarid){ - - return make_error(); - } -}; - -template -struct netcdf_encode...>, ToEncode> { - using Schema = schema::Struct...>; - - template - static error_or encode_member(const data& from, int ncid){ - using Type = typename parameter_pack_type::type; - constexpr string_literal Literal = parameter_key_pack_type::literal; - { - /** - * We have to ask for the internal id of the netcdf structure - */ - if constexpr (netcdf_is_group::value){ - return make_error(); - }else{ - int nc_varid{}; - int rc {}; - rc = nc_inq_varid(ncid, Literal.data.data(), &nc_varid); - if(rc != NC_NOERR) { - return make_error(); - } - auto eov = netcdf_encode::encode(from.template get(), ncid, nc_varid); - if(eov.is_error()){ - return eov; - } - } - - } - if constexpr ((i+1) < sizeof...(T)){ - auto eov = encode_member(from, ncid); - if(eov.is_error()){ - return eov; - } - } - - return void_t{}; - } - - static error_or encode(const data& from, int ncid){ - if constexpr (sizeof...(T) > 0){ - auto eov = encode_member<0>(from, ncid); - return eov; - } - - return void_t{}; - } - - template - static error_or encode_meta_member(const data& from, int ncid){ - using Type = typename parameter_pack_type::type; - constexpr string_literal Literal = parameter_key_pack_type::literal; - { - /** - * We have to ask for the internal id of the netcdf structure - */ - if constexpr (netcdf_is_group::value){ - return make_error(); - }else{ - int nc_varid{}; - int rc {}; - rc = nc_def_var(ncid, Literal.data.data(), netcdf_primitive_id::value, 0, nullptr, &nc_varid); - if(rc != NC_NOERR) { - return make_error(); - } - auto eov = netcdf_encode::encode_meta(from.template get(), ncid, nc_varid); - if(eov.is_error()){ - return eov; - } - } - - } - if constexpr ((i+1) < sizeof...(T)){ - auto eov = encode_meta_member(from, ncid); - if(eov.is_error()){ - return eov; - } - } - - return void_t{}; - } - - static error_or encode_meta(const data& from, int ncid){ - if constexpr (sizeof...(T) > 0){ - auto eov = encode_meta_member<0>(from, ncid); - return eov; - } - - return void_t{}; - } -}; - -template -struct netcdf_decode; - -template -struct netcdf_decode, ToDecode> { - using Schema = schema::Primitive; - - static error_or decode(data& to, int from, int nc_varid){ - int rc{}; - - nc_type nc_vartype{}; - int nc_dimnum{}; - std::array nc_dimids; - - rc = nc_inq_var(from, nc_varid, nullptr, &nc_vartype, &nc_dimnum, &nc_dimids[0], nullptr); - if(rc != NC_NOERR){ - return make_error(); - } - if(nc_vartype != netcdf_primitive_id>::value){ - return make_error(); - } - if(nc_dimnum != 0){ - return make_error(); - } - - typename native_data_type>::type val{}; - rc = nc_get_var(from, nc_varid, &val); - if(rc != NC_NOERR){ - return make_error(); - } - - to.set(val); - - return void_t {}; - } -}; - -template -struct netcdf_decode, ToDecode> { - using Schema = schema::Array; - - template - static error_or decode_level(data& to, int from, int nc_varid, std::array& index, const std::array& count){ - if constexpr ( Level == Dim ){ - int rc{}; - typename native_data_type::type val; - rc = nc_get_vara(from, nc_varid, index.data(), count.data(), &val); - if(rc != NC_NOERR){ - return make_error(); - } - to.at(index).set(val); - }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(to, from, nc_varid, index, count); - if(eov.is_error()){ - return eov; - } - } - } - - return void_t{}; - } - - static error_or decode(data& to, int from, int nc_varid){ - int rc{}; - - nc_type nc_vartype{}; - - int nc_dimnum{}; - std::array nc_dimids; - - rc = nc_inq_var(from, nc_varid, nullptr, &nc_vartype, &nc_dimnum, &nc_dimids[0], nullptr); - if(rc != NC_NOERR){ - return make_error(); - } - if(nc_vartype != netcdf_primitive_id::value){ - return make_error(); - } - if(nc_dimnum != Dim){ - return make_error(); - } - - std::array dims; - std::array count; - for(std::size_t i = 0; i < Dim; ++i){ - rc = nc_inq_dim(from, nc_dimids[i], nullptr, &dims[i]); - if(rc != NC_NOERR){ - return make_error(); - } - count[i] = 1; - } - - to = {dims}; - std::array index; - - return decode_level<0>(to, from, nc_varid, index, count); - } -}; - -template -struct netcdf_decode...>, ToDecode> { - using Schema = schema::Struct...>; - - template - static error_or decode_member(data& to, int from){ - using Type = typename parameter_pack_type::type; - constexpr string_literal Literal = parameter_key_pack_type::literal; - { - /** - * We have to ask for the internal id of the netcdf structure - */ - if constexpr (netcdf_is_group::value){ - int nc_group_id{}; - int rc {}; - rc = nc_inq_ncid(from, Literal.data.data(), &nc_group_id); - if(rc != NC_NOERR) { - return make_error(); - } - auto eov = netcdf_decode::decode(to.template get(), nc_group_id); - if(eov.is_error()){ - return eov; - } - }else{ - int nc_varid{}; - int rc {}; - rc = nc_inq_varid(from, Literal.data.data(), &nc_varid); - if(rc != NC_NOERR) { - return make_error(); - } - auto eov = netcdf_decode::decode(to.template get(), from, nc_varid); - if(eov.is_error()){ - return eov; - } - } - - } - if constexpr ((i+1) < sizeof...(T)){ - auto eov = decode_member(to, from); - if(eov.is_error()){ - return eov; - } - } - - return void_t{}; - } - - - static error_or decode(data& to, int from){ - if constexpr (sizeof...(T) > 0){ - auto eov = decode_member<0>(to, from); - return eov; - } - - return void_t{}; - } -}; -} -} diff --git a/modules/codec-netcdf/c++/netcdf.tmpl.hpp b/modules/codec-netcdf/c++/netcdf.tmpl.hpp new file mode 100644 index 0000000..bf257e4 --- /dev/null +++ b/modules/codec-netcdf/c++/netcdf.tmpl.hpp @@ -0,0 +1,348 @@ +#pragma once + +namespace saw { +namespace impl { +template +struct netcdf_primitive_id { + static_assert(always_false, "Not a primitive id"); +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_INT; +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_UINT; +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_INT64; +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_UINT64; +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_FLOAT; +}; + +template<> +struct netcdf_primitive_id { + static constexpr nc_type value = NC_DOUBLE; +}; + +template +struct netcdf_is_group { + static constexpr bool value = false; +}; + +template +struct netcdf_is_group...>> { + static constexpr bool value = true; +}; + +template +struct netcdf_encode; + +template +struct netcdf_encode, ToEncode> { + using Schema = schema::Primitive; + + static error_or encode(const data& from, int ncid, int ncvarid){ + int rc{}; + + typename native_data_type::type val = from.get(); + + rc = nc_put_var(ncid, ncvarid, &val); + if(rc != NC_NOERR) { + return make_error(); + } + + return void_t{}; + } + + static error_or encode_meta(const data& from, int ncid, int ncvarid){ + (void) from; + (void) ncid; + (void) ncvarid; + return void_t{}; + } +}; + +template +struct netcdf_encode, ToEncode> { + using Schema = schema::Array; + + template + static error_or encode_level(data& from, int ncid, int ncvarid){ + + return make_error(); + } + + static error_or encode(data& from, int ncid, int ncvarid){ + + return make_error(); + } + + static error_or encode_meta(const data& from, int ncid, int ncvarid){ + + return make_error(); + } +}; + +template +struct netcdf_encode...>, ToEncode> { + using Schema = schema::Struct...>; + + template + static error_or encode_member(const data& from, int ncid){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Literal = parameter_key_pack_type::literal; + { + /** + * We have to ask for the internal id of the netcdf structure + */ + if constexpr (netcdf_is_group::value){ + return make_error(); + }else{ + int nc_varid{}; + int rc {}; + rc = nc_inq_varid(ncid, Literal.data.data(), &nc_varid); + if(rc != NC_NOERR) { + return make_error(); + } + auto eov = netcdf_encode::encode(from.template get(), ncid, nc_varid); + if(eov.is_error()){ + return eov; + } + } + + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = encode_member(from, ncid); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } + + static error_or encode(const data& from, int ncid){ + if constexpr (sizeof...(T) > 0){ + auto eov = encode_member<0>(from, ncid); + return eov; + } + + return void_t{}; + } + + template + static error_or encode_meta_member(const data& from, int ncid){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Literal = parameter_key_pack_type::literal; + { + /** + * We have to ask for the internal id of the netcdf structure + */ + if constexpr (netcdf_is_group::value){ + return make_error(); + }else{ + int nc_varid{}; + int rc {}; + rc = nc_def_var(ncid, Literal.data.data(), netcdf_primitive_id::value, 0, nullptr, &nc_varid); + if(rc != NC_NOERR) { + return make_error(); + } + auto eov = netcdf_encode::encode_meta(from.template get(), ncid, nc_varid); + if(eov.is_error()){ + return eov; + } + } + + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = encode_meta_member(from, ncid); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } + + static error_or encode_meta(const data& from, int ncid){ + if constexpr (sizeof...(T) > 0){ + auto eov = encode_meta_member<0>(from, ncid); + return eov; + } + + return void_t{}; + } +}; + +template +struct netcdf_decode; + +template +struct netcdf_decode, ToDecode> { + using Schema = schema::Primitive; + + static error_or decode(data& to, int from, int nc_varid){ + int rc{}; + + nc_type nc_vartype{}; + int nc_dimnum{}; + std::array nc_dimids; + + rc = nc_inq_var(from, nc_varid, nullptr, &nc_vartype, &nc_dimnum, &nc_dimids[0], nullptr); + if(rc != NC_NOERR){ + return make_error(); + } + if(nc_vartype != netcdf_primitive_id>::value){ + return make_error(); + } + if(nc_dimnum != 0){ + return make_error(); + } + + typename native_data_type>::type val{}; + rc = nc_get_var(from, nc_varid, &val); + if(rc != NC_NOERR){ + return make_error(); + } + + to.set(val); + + return void_t {}; + } +}; + +template +struct netcdf_decode, ToDecode> { + using Schema = schema::Array; + + template + static error_or decode_level(data& to, int from, int nc_varid, std::array& index, const std::array& count){ + if constexpr ( Level == Dim ){ + int rc{}; + typename native_data_type::type val; + rc = nc_get_vara(from, nc_varid, index.data(), count.data(), &val); + if(rc != NC_NOERR){ + return make_error(); + } + to.at(index).set(val); + }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(to, from, nc_varid, index, count); + if(eov.is_error()){ + return eov; + } + } + } + + return void_t{}; + } + + static error_or decode(data& to, int from, int nc_varid){ + int rc{}; + + nc_type nc_vartype{}; + + int nc_dimnum{}; + std::array nc_dimids; + + rc = nc_inq_var(from, nc_varid, nullptr, &nc_vartype, &nc_dimnum, &nc_dimids[0], nullptr); + if(rc != NC_NOERR){ + return make_error(); + } + if(nc_vartype != netcdf_primitive_id::value){ + return make_error(); + } + if(nc_dimnum != Dim){ + return make_error(); + } + + std::array dims; + std::array count; + for(std::size_t i = 0; i < Dim; ++i){ + rc = nc_inq_dim(from, nc_dimids[i], nullptr, &dims[i]); + if(rc != NC_NOERR){ + return make_error(); + } + count[i] = 1; + } + + to = {dims}; + std::array index; + + return decode_level<0>(to, from, nc_varid, index, count); + } +}; + +template +struct netcdf_decode...>, ToDecode> { + using Schema = schema::Struct...>; + + template + static error_or decode_member(data& to, int from){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Literal = parameter_key_pack_type::literal; + { + /** + * We have to ask for the internal id of the netcdf structure + */ + if constexpr (netcdf_is_group::value){ + int nc_group_id{}; + int rc {}; + rc = nc_inq_ncid(from, Literal.data.data(), &nc_group_id); + if(rc != NC_NOERR) { + return make_error(); + } + auto eov = netcdf_decode::decode(to.template get(), nc_group_id); + if(eov.is_error()){ + return eov; + } + }else{ + int nc_varid{}; + int rc {}; + rc = nc_inq_varid(from, Literal.data.data(), &nc_varid); + if(rc != NC_NOERR) { + return make_error(); + } + auto eov = netcdf_decode::decode(to.template get(), from, nc_varid); + if(eov.is_error()){ + return eov; + } + } + + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = decode_member(to, from); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } + + + static error_or decode(data& to, int from){ + if constexpr (sizeof...(T) > 0){ + auto eov = decode_member<0>(to, from); + return eov; + } + + return void_t{}; + } +}; +} +} diff --git a/modules/codec/c++/args.h b/modules/codec/c++/args.h deleted file mode 100644 index 6bb75a2..0000000 --- a/modules/codec/c++/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++/args.hpp b/modules/codec/c++/args.hpp new file mode 100644 index 0000000..fc5037e --- /dev/null +++ b/modules/codec/c++/args.hpp @@ -0,0 +1,123 @@ +#pragma once + +#include "schema.hpp + +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++/crc32.h b/modules/codec/c++/crc32.h deleted file mode 100644 index c67c16e..0000000 --- a/modules/codec/c++/crc32.h +++ /dev/null @@ -1,114 +0,0 @@ -#pragma once - -#include -#include "schema.h" -#include "data.h" - -namespace saw { -namespace algs { -struct crc32 { - using Schema = schema::UInt32; - using Type = typename native_data_type::type; -}; -} - -template -struct hash {}; - -template<> -struct hash { - using Type = typename algs::crc32::Type; - - template - static constexpr Type update(Type crc, const T* data, uint64_t len){ - static_assert(sizeof(T) == 1, "Only uint8_t and int8_t are allowed here"); - constexpr std::array table = { - 0x00000000U,0x04C11DB7U,0x09823B6EU,0x0D4326D9U, - 0x130476DCU,0x17C56B6BU,0x1A864DB2U,0x1E475005U, - 0x2608EDB8U,0x22C9F00FU,0x2F8AD6D6U,0x2B4BCB61U, - 0x350C9B64U,0x31CD86D3U,0x3C8EA00AU,0x384FBDBDU, - 0x4C11DB70U,0x48D0C6C7U,0x4593E01EU,0x4152FDA9U, - 0x5F15ADACU,0x5BD4B01BU,0x569796C2U,0x52568B75U, - 0x6A1936C8U,0x6ED82B7FU,0x639B0DA6U,0x675A1011U, - 0x791D4014U,0x7DDC5DA3U,0x709F7B7AU,0x745E66CDU, - 0x9823B6E0U,0x9CE2AB57U,0x91A18D8EU,0x95609039U, - 0x8B27C03CU,0x8FE6DD8BU,0x82A5FB52U,0x8664E6E5U, - 0xBE2B5B58U,0xBAEA46EFU,0xB7A96036U,0xB3687D81U, - 0xAD2F2D84U,0xA9EE3033U,0xA4AD16EAU,0xA06C0B5DU, - 0xD4326D90U,0xD0F37027U,0xDDB056FEU,0xD9714B49U, - 0xC7361B4CU,0xC3F706FBU,0xCEB42022U,0xCA753D95U, - 0xF23A8028U,0xF6FB9D9FU,0xFBB8BB46U,0xFF79A6F1U, - 0xE13EF6F4U,0xE5FFEB43U,0xE8BCCD9AU,0xEC7DD02DU, - 0x34867077U,0x30476DC0U,0x3D044B19U,0x39C556AEU, - 0x278206ABU,0x23431B1CU,0x2E003DC5U,0x2AC12072U, - 0x128E9DCFU,0x164F8078U,0x1B0CA6A1U,0x1FCDBB16U, - 0x018AEB13U,0x054BF6A4U,0x0808D07DU,0x0CC9CDCAU, - 0x7897AB07U,0x7C56B6B0U,0x71159069U,0x75D48DDEU, - 0x6B93DDDBU,0x6F52C06CU,0x6211E6B5U,0x66D0FB02U, - 0x5E9F46BFU,0x5A5E5B08U,0x571D7DD1U,0x53DC6066U, - 0x4D9B3063U,0x495A2DD4U,0x44190B0DU,0x40D816BAU, - 0xACA5C697U,0xA864DB20U,0xA527FDF9U,0xA1E6E04EU, - 0xBFA1B04BU,0xBB60ADFCU,0xB6238B25U,0xB2E29692U, - 0x8AAD2B2FU,0x8E6C3698U,0x832F1041U,0x87EE0DF6U, - 0x99A95DF3U,0x9D684044U,0x902B669DU,0x94EA7B2AU, - 0xE0B41DE7U,0xE4750050U,0xE9362689U,0xEDF73B3EU, - 0xF3B06B3BU,0xF771768CU,0xFA325055U,0xFEF34DE2U, - 0xC6BCF05FU,0xC27DEDE8U,0xCF3ECB31U,0xCBFFD686U, - 0xD5B88683U,0xD1799B34U,0xDC3ABDEDU,0xD8FBA05AU, - 0x690CE0EEU,0x6DCDFD59U,0x608EDB80U,0x644FC637U, - 0x7A089632U,0x7EC98B85U,0x738AAD5CU,0x774BB0EBU, - 0x4F040D56U,0x4BC510E1U,0x46863638U,0x42472B8FU, - 0x5C007B8AU,0x58C1663DU,0x558240E4U,0x51435D53U, - 0x251D3B9EU,0x21DC2629U,0x2C9F00F0U,0x285E1D47U, - 0x36194D42U,0x32D850F5U,0x3F9B762CU,0x3B5A6B9BU, - 0x0315D626U,0x07D4CB91U,0x0A97ED48U,0x0E56F0FFU, - 0x1011A0FAU,0x14D0BD4DU,0x19939B94U,0x1D528623U, - 0xF12F560EU,0xF5EE4BB9U,0xF8AD6D60U,0xFC6C70D7U, - 0xE22B20D2U,0xE6EA3D65U,0xEBA91BBCU,0xEF68060BU, - 0xD727BBB6U,0xD3E6A601U,0xDEA580D8U,0xDA649D6FU, - 0xC423CD6AU,0xC0E2D0DDU,0xCDA1F604U,0xC960EBB3U, - 0xBD3E8D7EU,0xB9FF90C9U,0xB4BCB610U,0xB07DABA7U, - 0xAE3AFBA2U,0xAAFBE615U,0xA7B8C0CCU,0xA379DD7BU, - 0x9B3660C6U,0x9FF77D71U,0x92B45BA8U,0x9675461FU, - 0x8832161AU,0x8CF30BADU,0x81B02D74U,0x857130C3U, - 0x5D8A9099U,0x594B8D2EU,0x5408ABF7U,0x50C9B640U, - 0x4E8EE645U,0x4A4FFBF2U,0x470CDD2BU,0x43CDC09CU, - 0x7B827D21U,0x7F436096U,0x7200464FU,0x76C15BF8U, - 0x68860BFDU,0x6C47164AU,0x61043093U,0x65C52D24U, - 0x119B4BE9U,0x155A565EU,0x18197087U,0x1CD86D30U, - 0x029F3D35U,0x065E2082U,0x0B1D065BU,0x0FDC1BECU, - 0x3793A651U,0x3352BBE6U,0x3E119D3FU,0x3AD08088U, - 0x2497D08DU,0x2056CD3AU,0x2D15EBE3U,0x29D4F654U, - 0xC5A92679U,0xC1683BCEU,0xCC2B1D17U,0xC8EA00A0U, - 0xD6AD50A5U,0xD26C4D12U,0xDF2F6BCBU,0xDBEE767CU, - 0xE3A1CBC1U,0xE760D676U,0xEA23F0AFU,0xEEE2ED18U, - 0xF0A5BD1DU,0xF464A0AAU,0xF9278673U,0xFDE69BC4U, - 0x89B8FD09U,0x8D79E0BEU,0x803AC667U,0x84FBDBD0U, - 0x9ABC8BD5U,0x9E7D9662U,0x933EB0BBU,0x97FFAD0CU, - 0xAFB010B1U,0xAB710D06U,0xA6322BDFU,0xA2F33668U, - 0xBCB4666DU,0xB8757BDAU,0xB5365D03U,0xB1F740B4U, - }; - - while(len > 0){ - uint8_t val = static_cast(*data); - crc = table[val ^ ((crc >> 24) & 0xff)] ^ (crc << 8); - ++data; - --len; - } - return crc; - } - - static constexpr Type update(Type crc, const std::string_view& s){ - return update(crc, s.data(), s.size()); - } - - template - static constexpr Type apply(const T* data, uint64_t len){ - return update(0xffffffff, data, len) ^ 0xffffffff; - } - - static constexpr Type apply(const std::string_view& s){ - return apply(s.data(), s.size()); - } -}; -} diff --git a/modules/codec/c++/crc32.hpp b/modules/codec/c++/crc32.hpp new file mode 100644 index 0000000..0d2f72b --- /dev/null +++ b/modules/codec/c++/crc32.hpp @@ -0,0 +1,114 @@ +#pragma once + +#include +#include "schema.hpp +#include "data.hpp + +namespace saw { +namespace algs { +struct crc32 { + using Schema = schema::UInt32; + using Type = typename native_data_type::type; +}; +} + +template +struct hash {}; + +template<> +struct hash { + using Type = typename algs::crc32::Type; + + template + static constexpr Type update(Type crc, const T* data, uint64_t len){ + static_assert(sizeof(T) == 1, "Only uint8_t and int8_t are allowed here"); + constexpr std::array table = { + 0x00000000U,0x04C11DB7U,0x09823B6EU,0x0D4326D9U, + 0x130476DCU,0x17C56B6BU,0x1A864DB2U,0x1E475005U, + 0x2608EDB8U,0x22C9F00FU,0x2F8AD6D6U,0x2B4BCB61U, + 0x350C9B64U,0x31CD86D3U,0x3C8EA00AU,0x384FBDBDU, + 0x4C11DB70U,0x48D0C6C7U,0x4593E01EU,0x4152FDA9U, + 0x5F15ADACU,0x5BD4B01BU,0x569796C2U,0x52568B75U, + 0x6A1936C8U,0x6ED82B7FU,0x639B0DA6U,0x675A1011U, + 0x791D4014U,0x7DDC5DA3U,0x709F7B7AU,0x745E66CDU, + 0x9823B6E0U,0x9CE2AB57U,0x91A18D8EU,0x95609039U, + 0x8B27C03CU,0x8FE6DD8BU,0x82A5FB52U,0x8664E6E5U, + 0xBE2B5B58U,0xBAEA46EFU,0xB7A96036U,0xB3687D81U, + 0xAD2F2D84U,0xA9EE3033U,0xA4AD16EAU,0xA06C0B5DU, + 0xD4326D90U,0xD0F37027U,0xDDB056FEU,0xD9714B49U, + 0xC7361B4CU,0xC3F706FBU,0xCEB42022U,0xCA753D95U, + 0xF23A8028U,0xF6FB9D9FU,0xFBB8BB46U,0xFF79A6F1U, + 0xE13EF6F4U,0xE5FFEB43U,0xE8BCCD9AU,0xEC7DD02DU, + 0x34867077U,0x30476DC0U,0x3D044B19U,0x39C556AEU, + 0x278206ABU,0x23431B1CU,0x2E003DC5U,0x2AC12072U, + 0x128E9DCFU,0x164F8078U,0x1B0CA6A1U,0x1FCDBB16U, + 0x018AEB13U,0x054BF6A4U,0x0808D07DU,0x0CC9CDCAU, + 0x7897AB07U,0x7C56B6B0U,0x71159069U,0x75D48DDEU, + 0x6B93DDDBU,0x6F52C06CU,0x6211E6B5U,0x66D0FB02U, + 0x5E9F46BFU,0x5A5E5B08U,0x571D7DD1U,0x53DC6066U, + 0x4D9B3063U,0x495A2DD4U,0x44190B0DU,0x40D816BAU, + 0xACA5C697U,0xA864DB20U,0xA527FDF9U,0xA1E6E04EU, + 0xBFA1B04BU,0xBB60ADFCU,0xB6238B25U,0xB2E29692U, + 0x8AAD2B2FU,0x8E6C3698U,0x832F1041U,0x87EE0DF6U, + 0x99A95DF3U,0x9D684044U,0x902B669DU,0x94EA7B2AU, + 0xE0B41DE7U,0xE4750050U,0xE9362689U,0xEDF73B3EU, + 0xF3B06B3BU,0xF771768CU,0xFA325055U,0xFEF34DE2U, + 0xC6BCF05FU,0xC27DEDE8U,0xCF3ECB31U,0xCBFFD686U, + 0xD5B88683U,0xD1799B34U,0xDC3ABDEDU,0xD8FBA05AU, + 0x690CE0EEU,0x6DCDFD59U,0x608EDB80U,0x644FC637U, + 0x7A089632U,0x7EC98B85U,0x738AAD5CU,0x774BB0EBU, + 0x4F040D56U,0x4BC510E1U,0x46863638U,0x42472B8FU, + 0x5C007B8AU,0x58C1663DU,0x558240E4U,0x51435D53U, + 0x251D3B9EU,0x21DC2629U,0x2C9F00F0U,0x285E1D47U, + 0x36194D42U,0x32D850F5U,0x3F9B762CU,0x3B5A6B9BU, + 0x0315D626U,0x07D4CB91U,0x0A97ED48U,0x0E56F0FFU, + 0x1011A0FAU,0x14D0BD4DU,0x19939B94U,0x1D528623U, + 0xF12F560EU,0xF5EE4BB9U,0xF8AD6D60U,0xFC6C70D7U, + 0xE22B20D2U,0xE6EA3D65U,0xEBA91BBCU,0xEF68060BU, + 0xD727BBB6U,0xD3E6A601U,0xDEA580D8U,0xDA649D6FU, + 0xC423CD6AU,0xC0E2D0DDU,0xCDA1F604U,0xC960EBB3U, + 0xBD3E8D7EU,0xB9FF90C9U,0xB4BCB610U,0xB07DABA7U, + 0xAE3AFBA2U,0xAAFBE615U,0xA7B8C0CCU,0xA379DD7BU, + 0x9B3660C6U,0x9FF77D71U,0x92B45BA8U,0x9675461FU, + 0x8832161AU,0x8CF30BADU,0x81B02D74U,0x857130C3U, + 0x5D8A9099U,0x594B8D2EU,0x5408ABF7U,0x50C9B640U, + 0x4E8EE645U,0x4A4FFBF2U,0x470CDD2BU,0x43CDC09CU, + 0x7B827D21U,0x7F436096U,0x7200464FU,0x76C15BF8U, + 0x68860BFDU,0x6C47164AU,0x61043093U,0x65C52D24U, + 0x119B4BE9U,0x155A565EU,0x18197087U,0x1CD86D30U, + 0x029F3D35U,0x065E2082U,0x0B1D065BU,0x0FDC1BECU, + 0x3793A651U,0x3352BBE6U,0x3E119D3FU,0x3AD08088U, + 0x2497D08DU,0x2056CD3AU,0x2D15EBE3U,0x29D4F654U, + 0xC5A92679U,0xC1683BCEU,0xCC2B1D17U,0xC8EA00A0U, + 0xD6AD50A5U,0xD26C4D12U,0xDF2F6BCBU,0xDBEE767CU, + 0xE3A1CBC1U,0xE760D676U,0xEA23F0AFU,0xEEE2ED18U, + 0xF0A5BD1DU,0xF464A0AAU,0xF9278673U,0xFDE69BC4U, + 0x89B8FD09U,0x8D79E0BEU,0x803AC667U,0x84FBDBD0U, + 0x9ABC8BD5U,0x9E7D9662U,0x933EB0BBU,0x97FFAD0CU, + 0xAFB010B1U,0xAB710D06U,0xA6322BDFU,0xA2F33668U, + 0xBCB4666DU,0xB8757BDAU,0xB5365D03U,0xB1F740B4U, + }; + + while(len > 0){ + uint8_t val = static_cast(*data); + crc = table[val ^ ((crc >> 24) & 0xff)] ^ (crc << 8); + ++data; + --len; + } + return crc; + } + + static constexpr Type update(Type crc, const std::string_view& s){ + return update(crc, s.data(), s.size()); + } + + template + static constexpr Type apply(const T* data, uint64_t len){ + return update(0xffffffff, data, len) ^ 0xffffffff; + } + + static constexpr Type apply(const std::string_view& s){ + return apply(s.data(), s.size()); + } +}; +} diff --git a/modules/codec/c++/csv.h b/modules/codec/c++/csv.h deleted file mode 100644 index d35bb2d..0000000 --- a/modules/codec/c++/csv.h +++ /dev/null @@ -1,216 +0,0 @@ -#pragma once - -#include -#include - -#include "data.h" -#include "stream_value.h" - -namespace saw { -namespace encode { -struct Csv {}; -} - -namespace impl { -template -struct csv_encode { - static_assert(always_false, "Case not supported"); -}; - -template -struct csv_encode, FromDecode> { - static_assert(Dim == 1, "Only one dimension is allowed."); - static_assert(!is_array::value, "Array of an array is not allowed."); - static_assert(is_tuple::value || is_struct::value, "Only struct or tuples allowed inside a csv array"); - - using Schema = schema::Array; - - static error_or encode(const data& from, buffer& to){ - if constexpr (is_struct::value){ - auto eov = csv_encode::encode_header(to); - if(eov.is_error()){ - return eov; - } - } - - for(std::size_t i = 0; i < from.size(); ++i){ - auto eov = csv_encode::encode(from.at(i), to); - if(eov.is_error()){ - return eov; - } - } - - return void_t{}; - } -}; - -template -struct csv_encode...>, FromDecode> { - using Schema = schema::Struct...>; - - template - static error_or encode_header_i(buffer& to){ - // Encode string - // - constexpr auto str_view = parameter_key_pack_type::literal; - - for(auto& iter : str_view.view()){ - auto eov = stream_value::encode(iter, to); - if(eov.is_error()){ - return eov; - } - } - - // Go to next string - if constexpr ( (i+1) < sizeof...(K)){ - /** - * Replace this with col separator - */ - constexpr std::string_view lit = ","; - for(int8_t iter : lit){ - auto eov = stream_value::encode(iter, to); - if(eov.is_error()){ - return eov; - } - } - return encode_header_i(to); - } - - { - /** - * Replace this with row separator - */ - constexpr std::string_view lit = "\r\n"; - for(int8_t iter : lit){ - auto eov = stream_value::encode(iter, to); - if ( eov.is_error()){ - return eov; - } - } - } - - return make_void(); - } - - static error_or encode_header(buffer& to){ - return encode_header_i<0>(to); - } - - template - static error_or encode_i(const data& from, buffer& to){ - constexpr auto str_view = parameter_key_pack_type::literal; - - { - auto eov = csv_encode::type, FromDecode>::encode(from.template get(), to); - if(eov.is_error()){ - return eov; - } - } - - if constexpr ( (i+1) < sizeof...(K)){ - /** - * Replace this with col separator - */ - constexpr std::string_view lit = ","; - for(int8_t iter : lit){ - auto eov = stream_value::encode(iter, to); - if(eov.is_error()){ - return eov; - } - } - return encode_i(from, to); - } - { - /** - * Replace this with row separator - */ - constexpr std::string_view lit = "\r\n"; - for(int8_t iter : lit){ - auto eov = stream_value::encode(iter, to); - if ( eov.is_error()){ - return eov; - } - } - } - - return make_void(); - } - - static error_or encode(const data& from, buffer& to){ - return encode_i<0>(from, to); - } -}; - -template -struct csv_encode { - using Schema = schema::String; - - static error_or encode(const data& from, buffer& to){ - for(size_t i = 0; i < from.size(); ++i){ - auto eov = stream_value::encode(from.at(i), to); - if(eov.is_error()){ - return eov; - } - } - return make_void(); - } -}; - -template -struct csv_encode, FromDecode> { - using Schema = schema::Primitive; - - static error_or encode(const data& from, buffer& to){ - std::string to_str; - try { - to_str = std::to_string(from.get()); - }catch(const std::exception& ){ - return make_error(); - } - for(auto iter : to_str){ - auto eov = stream_value::encode(iter, to); - if(eov.is_error()){ - return eov; - } - } - return make_void(); - } -}; -} - -template -class data { - private: - ring_buffer buffer_; - public: - data() = default; - - buffer& get_buffer(){ - return buffer_; - } -}; - -template -class codec { - static_assert(is_array::value, "Only an Array is allowed as a base value"); -public: - template - static error_or encode(const data& from, data& to){ - buffer_view buff_v{to.get_buffer()}; - - auto eov = impl::csv_encode::encode(from, buff_v); - if(eov.is_error()){ - return eov; - } - to.get_buffer().write_advance(buff_v.write_offset()); - - return eov; - } - - template - static error_or decode(data& from, data& to){ - - return make_error(); - } -}; -} diff --git a/modules/codec/c++/csv.hpp b/modules/codec/c++/csv.hpp new file mode 100644 index 0000000..1cb4263 --- /dev/null +++ b/modules/codec/c++/csv.hpp @@ -0,0 +1,216 @@ +#pragma once + +#include +#include + +#include "data.hpp +#include "stream_value.hpp + +namespace saw { +namespace encode { +struct Csv {}; +} + +namespace impl { +template +struct csv_encode { + static_assert(always_false, "Case not supported"); +}; + +template +struct csv_encode, FromDecode> { + static_assert(Dim == 1, "Only one dimension is allowed."); + static_assert(!is_array::value, "Array of an array is not allowed."); + static_assert(is_tuple::value || is_struct::value, "Only struct or tuples allowed inside a csv array"); + + using Schema = schema::Array; + + static error_or encode(const data& from, buffer& to){ + if constexpr (is_struct::value){ + auto eov = csv_encode::encode_header(to); + if(eov.is_error()){ + return eov; + } + } + + for(std::size_t i = 0; i < from.size(); ++i){ + auto eov = csv_encode::encode(from.at(i), to); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } +}; + +template +struct csv_encode...>, FromDecode> { + using Schema = schema::Struct...>; + + template + static error_or encode_header_i(buffer& to){ + // Encode string + // + constexpr auto str_view = parameter_key_pack_type::literal; + + for(auto& iter : str_view.view()){ + auto eov = stream_value::encode(iter, to); + if(eov.is_error()){ + return eov; + } + } + + // Go to next string + if constexpr ( (i+1) < sizeof...(K)){ + /** + * Replace this with col separator + */ + constexpr std::string_view lit = ","; + for(int8_t iter : lit){ + auto eov = stream_value::encode(iter, to); + if(eov.is_error()){ + return eov; + } + } + return encode_header_i(to); + } + + { + /** + * Replace this with row separator + */ + constexpr std::string_view lit = "\r\n"; + for(int8_t iter : lit){ + auto eov = stream_value::encode(iter, to); + if ( eov.is_error()){ + return eov; + } + } + } + + return make_void(); + } + + static error_or encode_header(buffer& to){ + return encode_header_i<0>(to); + } + + template + static error_or encode_i(const data& from, buffer& to){ + constexpr auto str_view = parameter_key_pack_type::literal; + + { + auto eov = csv_encode::type, FromDecode>::encode(from.template get(), to); + if(eov.is_error()){ + return eov; + } + } + + if constexpr ( (i+1) < sizeof...(K)){ + /** + * Replace this with col separator + */ + constexpr std::string_view lit = ","; + for(int8_t iter : lit){ + auto eov = stream_value::encode(iter, to); + if(eov.is_error()){ + return eov; + } + } + return encode_i(from, to); + } + { + /** + * Replace this with row separator + */ + constexpr std::string_view lit = "\r\n"; + for(int8_t iter : lit){ + auto eov = stream_value::encode(iter, to); + if ( eov.is_error()){ + return eov; + } + } + } + + return make_void(); + } + + static error_or encode(const data& from, buffer& to){ + return encode_i<0>(from, to); + } +}; + +template +struct csv_encode { + using Schema = schema::String; + + static error_or encode(const data& from, buffer& to){ + for(size_t i = 0; i < from.size(); ++i){ + auto eov = stream_value::encode(from.at(i), to); + if(eov.is_error()){ + return eov; + } + } + return make_void(); + } +}; + +template +struct csv_encode, FromDecode> { + using Schema = schema::Primitive; + + static error_or encode(const data& from, buffer& to){ + std::string to_str; + try { + to_str = std::to_string(from.get()); + }catch(const std::exception& ){ + return make_error(); + } + for(auto iter : to_str){ + auto eov = stream_value::encode(iter, to); + if(eov.is_error()){ + return eov; + } + } + return make_void(); + } +}; +} + +template +class data { + private: + ring_buffer buffer_; + public: + data() = default; + + buffer& get_buffer(){ + return buffer_; + } +}; + +template +class codec { + static_assert(is_array::value, "Only an Array is allowed as a base value"); +public: + template + static error_or encode(const data& from, data& to){ + buffer_view buff_v{to.get_buffer()}; + + auto eov = impl::csv_encode::encode(from, buff_v); + if(eov.is_error()){ + return eov; + } + to.get_buffer().write_advance(buff_v.write_offset()); + + return eov; + } + + 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 deleted file mode 100644 index f8fdf88..0000000 --- a/modules/codec/c++/data.h +++ /dev/null @@ -1,451 +0,0 @@ -#pragma once - -#include -#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_; - - uint64_t get_full_size() const { - uint64_t s = 1; - - for(uint64_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 - error_or add(saw::data data){ - /** @todo - * Generally the last dimension can always accept a element so to say. - * Changing the others would require moving data due to the stride changing. - * Since the last dimension doesn't affect the stride, we don't need reordering there. - * But I want a quick solution for one dimension so here we are. - * - * I can always ignore strides and use a stacked std::vector - * std::vector> and so on. - * But for now I'm keeping the strides. Smaller chunks of memory aren't to bad either - * though. - * I'll probably change it to the smaller chunks - */ - static_assert(Dim == 1, "Currently can't deal with higher dims"); - static_assert(i < Dim, "Can't add to dimension. Index i larger than dimension size"); - - try { - value_.emplace_back(std::move(data)); - }catch(const std::exception& e){ - (void) e; - return make_error(); - } - - ++dims_.at(i); - - return void_t{}; - } - - template - data(Dims... size_): - data{{static_cast(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({static_cast(i)...})); - } - - template - const data& at(Dims... i) const { - return value_.at(this->get_flat_index({static_cast(i)...})); - } - - data& at(const data>& i){ - return value_.at(this->get_flat_index(i)); - } - - const data& at(const data>& 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();} - - data> get_dims() const { - return {dims_}; - } - -private: - uint64_t get_flat_index(const std::array& i) const { - return get_flat_index(data>{i}); - } - - uint64_t get_flat_index(const data>& i) const { - uint64_t s = 0; - - uint64_t stride = 1; - - for(uint64_t iter = 0; iter < Dim; ++iter){ - assert(i.at(iter).get() < dims_.at(iter)); - s += i.at(iter).get() * 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_; - using ArrayT = std::array, ct_multiply::value>; - ArrayT value_; - -public: - data() = default; - - data(const std::array::type, ct_multiply::value>& data) requires (is_primitive::value) - { - for(uint64_t i = 0; i < ct_multiply::value; ++i){ - value_.at(i).set(data.at(i)); - } - } - - 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...})); - } - - data& at(const data>& i){ - return value_.at(this->get_flat_index(i)); - } - - const data& at(const data>& i)const{ - return value_.at(this->get_flat_index(i)); - } - - template - uint64_t get_dim_size() const { - return parameter_pack_value::value; - } - - data> get_dims() const { - return {std::array{D...}}; - } -private: - uint64_t get_flat_index(const std::array& i) const { - uint64_t s = 0; - - uint64_t stride = 1; - - constexpr static std::array dims_{D...}; - - for(uint64_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_;} - - data, encode::Native> operator*(const saw::data, encode::Native>& rhs)const{ - return {get() * rhs.get()}; - } - - data, encode::Native> operator/(const saw::data, encode::Native>& rhs)const{ - return {get() / rhs.get()}; - } - - data, encode::Native> operator+(const saw::data, encode::Native>& rhs)const{ - return {get() + rhs.get()}; - } - - data, encode::Native> operator-(const saw::data, encode::Native>& rhs)const{ - return {get() - rhs.get()}; - } -}; - - -} diff --git a/modules/codec/c++/data.hpp b/modules/codec/c++/data.hpp new file mode 100644 index 0000000..3aebc89 --- /dev/null +++ b/modules/codec/c++/data.hpp @@ -0,0 +1,451 @@ +#pragma once + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "schema.hpp + +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_; + + uint64_t get_full_size() const { + uint64_t s = 1; + + for(uint64_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 + error_or add(saw::data data){ + /** @todo + * Generally the last dimension can always accept a element so to say. + * Changing the others would require moving data due to the stride changing. + * Since the last dimension doesn't affect the stride, we don't need reordering there. + * But I want a quick solution for one dimension so here we are. + * + * I can always ignore strides and use a stacked std::vector + * std::vector> and so on. + * But for now I'm keeping the strides. Smaller chunks of memory aren't to bad either + * though. + * I'll probably change it to the smaller chunks + */ + static_assert(Dim == 1, "Currently can't deal with higher dims"); + static_assert(i < Dim, "Can't add to dimension. Index i larger than dimension size"); + + try { + value_.emplace_back(std::move(data)); + }catch(const std::exception& e){ + (void) e; + return make_error(); + } + + ++dims_.at(i); + + return void_t{}; + } + + template + data(Dims... size_): + data{{static_cast(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({static_cast(i)...})); + } + + template + const data& at(Dims... i) const { + return value_.at(this->get_flat_index({static_cast(i)...})); + } + + data& at(const data>& i){ + return value_.at(this->get_flat_index(i)); + } + + const data& at(const data>& 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();} + + data> get_dims() const { + return {dims_}; + } + +private: + uint64_t get_flat_index(const std::array& i) const { + return get_flat_index(data>{i}); + } + + uint64_t get_flat_index(const data>& i) const { + uint64_t s = 0; + + uint64_t stride = 1; + + for(uint64_t iter = 0; iter < Dim; ++iter){ + assert(i.at(iter).get() < dims_.at(iter)); + s += i.at(iter).get() * 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_; + using ArrayT = std::array, ct_multiply::value>; + ArrayT value_; + +public: + data() = default; + + data(const std::array::type, ct_multiply::value>& data) requires (is_primitive::value) + { + for(uint64_t i = 0; i < ct_multiply::value; ++i){ + value_.at(i).set(data.at(i)); + } + } + + 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...})); + } + + data& at(const data>& i){ + return value_.at(this->get_flat_index(i)); + } + + const data& at(const data>& i)const{ + return value_.at(this->get_flat_index(i)); + } + + template + uint64_t get_dim_size() const { + return parameter_pack_value::value; + } + + data> get_dims() const { + return {std::array{D...}}; + } +private: + uint64_t get_flat_index(const std::array& i) const { + uint64_t s = 0; + + uint64_t stride = 1; + + constexpr static std::array dims_{D...}; + + for(uint64_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_;} + + data, encode::Native> operator*(const saw::data, encode::Native>& rhs)const{ + return {get() * rhs.get()}; + } + + data, encode::Native> operator/(const saw::data, encode::Native>& rhs)const{ + return {get() / rhs.get()}; + } + + data, encode::Native> operator+(const saw::data, encode::Native>& rhs)const{ + return {get() + rhs.get()}; + } + + data, encode::Native> operator-(const saw::data, encode::Native>& rhs)const{ + return {get() - rhs.get()}; + } +}; + + +} diff --git a/modules/codec/c++/forst.h b/modules/codec/c++/forst.h deleted file mode 100644 index 7e8fbf0..0000000 --- a/modules/codec/c++/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/c++/forst.hpp b/modules/codec/c++/forst.hpp new file mode 100644 index 0000000..aa1532b --- /dev/null +++ b/modules/codec/c++/forst.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "data.hpp + +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 deleted file mode 100644 index 30d18ef..0000000 --- a/modules/codec/c++/forst.tmpl.h +++ /dev/null @@ -1,7 +0,0 @@ -namespace saw { -namespace impl { -struct forst_decode { - -}; -} -} diff --git a/modules/codec/c++/forst.tmpl.hpp b/modules/codec/c++/forst.tmpl.hpp new file mode 100644 index 0000000..30d18ef --- /dev/null +++ b/modules/codec/c++/forst.tmpl.hpp @@ -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 deleted file mode 100644 index 89bfc26..0000000 --- a/modules/codec/c++/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/c++/interface.hpp b/modules/codec/c++/interface.hpp new file mode 100644 index 0000000..7f7deb4 --- /dev/null +++ b/modules/codec/c++/interface.hpp @@ -0,0 +1,103 @@ +#pragma once + +#include +#include "schema.hpp +#include "data.hpp + +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 deleted file mode 100644 index e275102..0000000 --- a/modules/codec/c++/rpc.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -namespace saw { -template -class remote { - static_assert(always_false, "Type of remote not supported"); - - template - rpc_client connect(); -}; - -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++/rpc.hpp b/modules/codec/c++/rpc.hpp new file mode 100644 index 0000000..e275102 --- /dev/null +++ b/modules/codec/c++/rpc.hpp @@ -0,0 +1,29 @@ +#pragma once + +namespace saw { +template +class remote { + static_assert(always_false, "Type of remote not supported"); + + template + rpc_client connect(); +}; + +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 deleted file mode 100644 index 4549916..0000000 --- a/modules/codec/c++/schema.h +++ /dev/null @@ -1,172 +0,0 @@ -#pragma once - -#include -#include - -namespace saw { -namespace schema { -// NOLINTBEGIN -template struct Member { - static constexpr string_literal name = "Member"; -}; - -template struct Struct { - static_assert( - always_false, - "This schema template doesn't support this type of template argument"); -}; - -template -struct Struct...> { - static constexpr string_literal name = "Struct"; -}; - -template struct Union { - static_assert( - always_false, - "This schema template doesn't support this type of template argument"); -}; - -template -struct Union...> { - static constexpr string_literal name = "Union"; -}; - -template struct Array { - static constexpr string_literal name = "Array"; -}; - -template struct FixedArray { - static constexpr string_literal name = "FixedArray"; -}; - -template struct Tuple { - static constexpr string_literal name = "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 { - static constexpr string_literal name = "Wrapper"; -}; - -struct String { - static constexpr string_literal name = "String"; -}; - - -struct SignedInteger { - static constexpr string_literal name = "SignedInteger"; -}; -struct UnsignedInteger { - static constexpr string_literal name = "UnsignedInteger"; -}; -struct FloatingPoint { - static constexpr string_literal name = "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"); - static constexpr string_literal name = "Primitive"; -}; - -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 { - static constexpr string_literal name = "VariableLengthPrimitive"; -}; - -using VarInt = VariableLengthPrimitive; -using VarLong = VariableLengthPrimitive; - -/** - * Classes enabling Rpc calls - */ -template -struct Function { - static constexpr string_literal name = "Function"; -}; - -template struct Interface { - static_assert( - always_false, - "This schema template doesn't support this type of template argument"); - - static constexpr string_literal name = "Interface"; -}; - -template -struct Interface,Names>...> { - static constexpr string_literal name = "Interface"; -}; - -// NOLINTEND -} // namespace schema -template struct is_struct { - constexpr static bool value = false; -}; - -template struct is_struct...>> { - constexpr static bool value = true; -}; - -template struct is_string { - constexpr static bool value = false; -}; - -template <> struct is_string { - constexpr static bool value = true; -}; - -template struct is_tuple { - constexpr static bool value = false; -}; - -template struct is_tuple> { - constexpr static bool value = true; -}; - -template struct is_array { - constexpr static bool value = false; -}; - -template struct is_array> { - constexpr static bool value = true; -}; - -template struct is_primitive { - constexpr static bool value = false; -}; - -template struct is_primitive> { - constexpr static bool value = true; -}; -} // namespace saw diff --git a/modules/codec/c++/schema.hpp b/modules/codec/c++/schema.hpp new file mode 100644 index 0000000..4549916 --- /dev/null +++ b/modules/codec/c++/schema.hpp @@ -0,0 +1,172 @@ +#pragma once + +#include +#include + +namespace saw { +namespace schema { +// NOLINTBEGIN +template struct Member { + static constexpr string_literal name = "Member"; +}; + +template struct Struct { + static_assert( + always_false, + "This schema template doesn't support this type of template argument"); +}; + +template +struct Struct...> { + static constexpr string_literal name = "Struct"; +}; + +template struct Union { + static_assert( + always_false, + "This schema template doesn't support this type of template argument"); +}; + +template +struct Union...> { + static constexpr string_literal name = "Union"; +}; + +template struct Array { + static constexpr string_literal name = "Array"; +}; + +template struct FixedArray { + static constexpr string_literal name = "FixedArray"; +}; + +template struct Tuple { + static constexpr string_literal name = "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 { + static constexpr string_literal name = "Wrapper"; +}; + +struct String { + static constexpr string_literal name = "String"; +}; + + +struct SignedInteger { + static constexpr string_literal name = "SignedInteger"; +}; +struct UnsignedInteger { + static constexpr string_literal name = "UnsignedInteger"; +}; +struct FloatingPoint { + static constexpr string_literal name = "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"); + static constexpr string_literal name = "Primitive"; +}; + +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 { + static constexpr string_literal name = "VariableLengthPrimitive"; +}; + +using VarInt = VariableLengthPrimitive; +using VarLong = VariableLengthPrimitive; + +/** + * Classes enabling Rpc calls + */ +template +struct Function { + static constexpr string_literal name = "Function"; +}; + +template struct Interface { + static_assert( + always_false, + "This schema template doesn't support this type of template argument"); + + static constexpr string_literal name = "Interface"; +}; + +template +struct Interface,Names>...> { + static constexpr string_literal name = "Interface"; +}; + +// NOLINTEND +} // namespace schema +template struct is_struct { + constexpr static bool value = false; +}; + +template struct is_struct...>> { + constexpr static bool value = true; +}; + +template struct is_string { + constexpr static bool value = false; +}; + +template <> struct is_string { + constexpr static bool value = true; +}; + +template struct is_tuple { + constexpr static bool value = false; +}; + +template struct is_tuple> { + constexpr static bool value = true; +}; + +template struct is_array { + constexpr static bool value = false; +}; + +template struct is_array> { + constexpr static bool value = true; +}; + +template struct is_primitive { + constexpr static bool value = false; +}; + +template struct is_primitive> { + constexpr static bool value = true; +}; +} // namespace saw diff --git a/modules/codec/c++/schema_factory.h b/modules/codec/c++/schema_factory.h deleted file mode 100644 index bb8588f..0000000 --- a/modules/codec/c++/schema_factory.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "schema.h" - -namespace saw { -template -struct schema_factory { - using Schema = T; - static_assert(always_false, "Not supported"); -}; - -template -struct schema_factory...>> { - using Schema = schema::Struct...>; - - template - constexpr schema_factory...,schema::Member>> add() const noexcept { - return {}; - } -}; - -template -struct schema_factory...>> { - using Schema = schema::Union...>; - - template - constexpr schema_factory...,schema::Member>> add() const noexcept { - return {}; - } -}; - -template -struct schema_factory> { - using Schema = schema::Tuple; - - template - constexpr schema_factory> add() const noexcept { - return {}; - } -}; - -/** - * This creates the base schema. For example an empty struct,tuple,union or anything else. - */ -template -constexpr schema_factory build_schema() noexcept { - return {}; -} -} diff --git a/modules/codec/c++/schema_factory.hpp b/modules/codec/c++/schema_factory.hpp new file mode 100644 index 0000000..f39c93c --- /dev/null +++ b/modules/codec/c++/schema_factory.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include "schema.hpp + +namespace saw { +template +struct schema_factory { + using Schema = T; + static_assert(always_false, "Not supported"); +}; + +template +struct schema_factory...>> { + using Schema = schema::Struct...>; + + template + constexpr schema_factory...,schema::Member>> add() const noexcept { + return {}; + } +}; + +template +struct schema_factory...>> { + using Schema = schema::Union...>; + + template + constexpr schema_factory...,schema::Member>> add() const noexcept { + return {}; + } +}; + +template +struct schema_factory> { + using Schema = schema::Tuple; + + template + constexpr schema_factory> add() const noexcept { + return {}; + } +}; + +/** + * This creates the base schema. For example an empty struct,tuple,union or anything else. + */ +template +constexpr schema_factory build_schema() noexcept { + return {}; +} +} diff --git a/modules/codec/c++/schema_hash.h b/modules/codec/c++/schema_hash.h deleted file mode 100644 index 29afa5e..0000000 --- a/modules/codec/c++/schema_hash.h +++ /dev/null @@ -1,207 +0,0 @@ -#pragma once - -#include -#include "schema.h" -#include "crc32.h" - -namespace saw { -template -struct hash_literal { - static constexpr uint32_t apply(uint32_t seed){ - constexpr std::string_view view = lit.view(); - return hash::update(seed, view); - } -}; - -template -struct schema_hash_seed { - static_assert(always_false, "Not schema_hashable"); -}; - -template<> -struct schema_hash_seed { - using Schema = schema::SignedInteger; - - static constexpr uint32_t apply(uint32_t seed){ - return hash_literal::apply(seed); - } -}; - -template<> -struct schema_hash_seed { - using Schema = schema::UnsignedInteger; - - static constexpr uint32_t apply(uint32_t seed){ - return hash_literal::apply(seed); - } -}; - -template<> -struct schema_hash_seed { - using Schema = schema::FloatingPoint; - - static constexpr uint32_t apply(uint32_t seed){ - return hash_literal::apply(seed); - } -}; - -template<> -struct schema_hash_seed { - using Schema = schema::String; - - static constexpr uint32_t apply(uint32_t seed){ - return hash_literal::apply(seed); - } -}; - -template -struct schema_hash_seed> { - using Schema = schema::Primitive; - - static constexpr uint32_t apply(uint32_t seed){ - seed = hash_literal::apply(seed); - seed = schema_hash_seed

::apply(seed); - uint64_t val = N; - std::array dat{ - static_cast(val >> 0), - static_cast(val >> 8), - static_cast(val >> 16), - static_cast(val >> 24), - static_cast(val >> 32), - static_cast(val >> 40), - static_cast(val >> 48), - static_cast(val >> 56) - }; - seed = hash::update(seed, &dat[0], dat.size()); - return seed; - } -}; - -template -struct schema_hash_seed> { - using Schema = schema::Array; - - static constexpr uint32_t apply(uint32_t seed){ - seed = hash_literal::apply(seed); - seed = schema_hash_seed::apply(seed); - uint64_t val = N; - std::array dat{ - static_cast(val >> 0), - static_cast(val >> 8), - static_cast(val >> 16), - static_cast(val >> 24), - static_cast(val >> 32), - static_cast(val >> 40), - static_cast(val >> 48), - static_cast(val >> 56) - }; - seed = hash::update(seed, &dat[0], dat.size()); - return seed; - } -}; - -template -struct schema_hash_seed> { - using Schema = schema::Tuple; - - template - static constexpr uint32_t apply_ele(uint32_t seed){ - using Type = typename parameter_pack_type::type; - - seed = schema_hash_seed::apply(seed); - if constexpr ( (i+1) < sizeof...(T) ){ - return apply_ele(seed); - } - return seed; - } - - - static constexpr uint32_t apply(uint32_t seed){ - seed = hash_literal::apply(seed); - if constexpr (sizeof...(T) > 0){ - seed = apply_ele<0>(seed); - } - return seed; - } -}; - -template -struct schema_hash_seed...>> { - using Schema = schema::Struct...>; - - template - static constexpr uint32_t apply_ele(uint32_t seed){ - using Type = typename parameter_pack_type::type; - constexpr string_literal Lit = parameter_key_pack_type::literal; - using MemberT = typename parameter_pack_type...>::type; - - seed = hash_literal::apply(seed); - seed = schema_hash_seed::apply(seed); - seed = hash_literal::apply(seed); - - if constexpr ( (i+1) < sizeof...(V) ){ - return apply_ele(seed); - } - return seed; - } - - static constexpr uint32_t apply(uint32_t seed){ - seed = hash_literal::apply(seed); - if constexpr (sizeof...(V) > 0){ - seed = apply_ele<0>(seed); - } - return seed; - } -}; - -template -struct schema_hash_seed> { - using Schema = schema::Function; - - static constexpr uint32_t apply(uint32_t seed){ - seed = hash_literal::apply(seed); - seed = schema_hash_seed::apply(seed); - seed = schema_hash_seed::apply(seed); - return seed; - } -}; - -template -struct schema_hash_seed...>> { - using Schema = schema::Interface...>; - - template - static constexpr uint32_t apply_ele(uint32_t seed){ - using Type = typename parameter_pack_type::type; - constexpr string_literal Lit = parameter_key_pack_type::literal; - using MemberT = schema::Member; - - seed = hash_literal::apply(seed); - seed = schema_hash_seed::apply(seed); - seed = hash_literal::apply(seed); - - if constexpr ( (i+1) < sizeof...(T) ){ - return apply_ele(seed); - } - - return seed; - } - - static constexpr uint32_t apply(uint32_t seed){ - seed = hash_literal::apply(seed); - if constexpr ( sizeof...(T) > 0){ - seed = apply_ele<0>(seed); - } - return seed; - } -}; - -template -struct schema_hash { - static constexpr uint32_t apply() { - constexpr uint32_t seed = 0; - return schema_hash_seed::apply(seed); - } -}; - -} diff --git a/modules/codec/c++/schema_hash.hpp b/modules/codec/c++/schema_hash.hpp new file mode 100644 index 0000000..c799311 --- /dev/null +++ b/modules/codec/c++/schema_hash.hpp @@ -0,0 +1,207 @@ +#pragma once + +#include +#include "schema.hpp +#include "crc32.hpp + +namespace saw { +template +struct hash_literal { + static constexpr uint32_t apply(uint32_t seed){ + constexpr std::string_view view = lit.view(); + return hash::update(seed, view); + } +}; + +template +struct schema_hash_seed { + static_assert(always_false, "Not schema_hashable"); +}; + +template<> +struct schema_hash_seed { + using Schema = schema::SignedInteger; + + static constexpr uint32_t apply(uint32_t seed){ + return hash_literal::apply(seed); + } +}; + +template<> +struct schema_hash_seed { + using Schema = schema::UnsignedInteger; + + static constexpr uint32_t apply(uint32_t seed){ + return hash_literal::apply(seed); + } +}; + +template<> +struct schema_hash_seed { + using Schema = schema::FloatingPoint; + + static constexpr uint32_t apply(uint32_t seed){ + return hash_literal::apply(seed); + } +}; + +template<> +struct schema_hash_seed { + using Schema = schema::String; + + static constexpr uint32_t apply(uint32_t seed){ + return hash_literal::apply(seed); + } +}; + +template +struct schema_hash_seed> { + using Schema = schema::Primitive; + + static constexpr uint32_t apply(uint32_t seed){ + seed = hash_literal::apply(seed); + seed = schema_hash_seed

::apply(seed); + uint64_t val = N; + std::array dat{ + static_cast(val >> 0), + static_cast(val >> 8), + static_cast(val >> 16), + static_cast(val >> 24), + static_cast(val >> 32), + static_cast(val >> 40), + static_cast(val >> 48), + static_cast(val >> 56) + }; + seed = hash::update(seed, &dat[0], dat.size()); + return seed; + } +}; + +template +struct schema_hash_seed> { + using Schema = schema::Array; + + static constexpr uint32_t apply(uint32_t seed){ + seed = hash_literal::apply(seed); + seed = schema_hash_seed::apply(seed); + uint64_t val = N; + std::array dat{ + static_cast(val >> 0), + static_cast(val >> 8), + static_cast(val >> 16), + static_cast(val >> 24), + static_cast(val >> 32), + static_cast(val >> 40), + static_cast(val >> 48), + static_cast(val >> 56) + }; + seed = hash::update(seed, &dat[0], dat.size()); + return seed; + } +}; + +template +struct schema_hash_seed> { + using Schema = schema::Tuple; + + template + static constexpr uint32_t apply_ele(uint32_t seed){ + using Type = typename parameter_pack_type::type; + + seed = schema_hash_seed::apply(seed); + if constexpr ( (i+1) < sizeof...(T) ){ + return apply_ele(seed); + } + return seed; + } + + + static constexpr uint32_t apply(uint32_t seed){ + seed = hash_literal::apply(seed); + if constexpr (sizeof...(T) > 0){ + seed = apply_ele<0>(seed); + } + return seed; + } +}; + +template +struct schema_hash_seed...>> { + using Schema = schema::Struct...>; + + template + static constexpr uint32_t apply_ele(uint32_t seed){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Lit = parameter_key_pack_type::literal; + using MemberT = typename parameter_pack_type...>::type; + + seed = hash_literal::apply(seed); + seed = schema_hash_seed::apply(seed); + seed = hash_literal::apply(seed); + + if constexpr ( (i+1) < sizeof...(V) ){ + return apply_ele(seed); + } + return seed; + } + + static constexpr uint32_t apply(uint32_t seed){ + seed = hash_literal::apply(seed); + if constexpr (sizeof...(V) > 0){ + seed = apply_ele<0>(seed); + } + return seed; + } +}; + +template +struct schema_hash_seed> { + using Schema = schema::Function; + + static constexpr uint32_t apply(uint32_t seed){ + seed = hash_literal::apply(seed); + seed = schema_hash_seed::apply(seed); + seed = schema_hash_seed::apply(seed); + return seed; + } +}; + +template +struct schema_hash_seed...>> { + using Schema = schema::Interface...>; + + template + static constexpr uint32_t apply_ele(uint32_t seed){ + using Type = typename parameter_pack_type::type; + constexpr string_literal Lit = parameter_key_pack_type::literal; + using MemberT = schema::Member; + + seed = hash_literal::apply(seed); + seed = schema_hash_seed::apply(seed); + seed = hash_literal::apply(seed); + + if constexpr ( (i+1) < sizeof...(T) ){ + return apply_ele(seed); + } + + return seed; + } + + static constexpr uint32_t apply(uint32_t seed){ + seed = hash_literal::apply(seed); + if constexpr ( sizeof...(T) > 0){ + seed = apply_ele<0>(seed); + } + return seed; + } +}; + +template +struct schema_hash { + static constexpr uint32_t apply() { + constexpr uint32_t seed = 0; + return schema_hash_seed::apply(seed); + } +}; + +} diff --git a/modules/codec/c++/schema_stringify.h b/modules/codec/c++/schema_stringify.h deleted file mode 100644 index a82081a..0000000 --- a/modules/codec/c++/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/c++/schema_stringify.hpp b/modules/codec/c++/schema_stringify.hpp new file mode 100644 index 0000000..c8d8942 --- /dev/null +++ b/modules/codec/c++/schema_stringify.hpp @@ -0,0 +1,118 @@ +#pragma once + +#include "schema.hpp + +#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 deleted file mode 100644 index aff0626..0000000 --- a/modules/codec/c++/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/c++/simple.hpp b/modules/codec/c++/simple.hpp new file mode 100644 index 0000000..6582f35 --- /dev/null +++ b/modules/codec/c++/simple.hpp @@ -0,0 +1,389 @@ +#pragma once + +#include "data.hpp +#include "stream_value.hpp + +#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 deleted file mode 100644 index b5a58bd..0000000 --- a/modules/codec/c++/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/c++/stream_value.hpp b/modules/codec/c++/stream_value.hpp new file mode 100644 index 0000000..30dff75 --- /dev/null +++ b/modules/codec/c++/stream_value.hpp @@ -0,0 +1,64 @@ +#pragma once + +#include "schema.hpp + +#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/core/c++/test/suite.h b/modules/core/c++/test/suite.h deleted file mode 100644 index e28a94c..0000000 --- a/modules/core/c++/test/suite.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "../common.h" - -namespace saw { -namespace test { -class test_runner; -class test_case { -private: - std::string file; - uint line; - std::string description; - bool matched_filter; - test_case* next; - test_case** prev; - - friend class test_runner; -public: - test_case(const std::string& file_, uint line_, const std::string& description_); - ~test_case(); - - virtual void run() = 0; -}; -} -} -#define SAW_TEST(description) \ - class SAW_UNIQUE_NAME(test_case) : public ::saw::test::test_case { \ - public: \ - SAW_UNIQUE_NAME(test_case)(): ::saw::test::test_case(__FILE__,__LINE__,description) {} \ - void run() override; \ - }SAW_UNIQUE_NAME(test_case_); \ - void SAW_UNIQUE_NAME(test_case)::run() - -#define SAW_EXPECT(expr, msg_split) \ - if( ! (expr) ){ \ - auto msg = msg_split; \ - throw std::runtime_error{std::string{msg}};\ - } diff --git a/modules/core/c++/test/suite.hpp b/modules/core/c++/test/suite.hpp new file mode 100644 index 0000000..fd6ca68 --- /dev/null +++ b/modules/core/c++/test/suite.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include +#include + +#include "../common.hpp + +namespace saw { +namespace test { +class test_runner; +class test_case { +private: + std::string file; + uint line; + std::string description; + bool matched_filter; + test_case* next; + test_case** prev; + + friend class test_runner; +public: + test_case(const std::string& file_, uint line_, const std::string& description_); + ~test_case(); + + virtual void run() = 0; +}; +} +} +#define SAW_TEST(description) \ + class SAW_UNIQUE_NAME(test_case) : public ::saw::test::test_case { \ + public: \ + SAW_UNIQUE_NAME(test_case)(): ::saw::test::test_case(__FILE__,__LINE__,description) {} \ + void run() override; \ + }SAW_UNIQUE_NAME(test_case_); \ + void SAW_UNIQUE_NAME(test_case)::run() + +#define SAW_EXPECT(expr, msg_split) \ + if( ! (expr) ){ \ + auto msg = msg_split; \ + throw std::runtime_error{std::string{msg}};\ + } diff --git a/modules/device-hip/c++/rpc.h b/modules/device-hip/c++/rpc.h deleted file mode 100644 index 0bcda0c..0000000 --- a/modules/device-hip/c++/rpc.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include - -namespace saw { -namespace rmt { -struct DeviceHip {}; -} - -template<> -class remote { -private: -public: - template - error_or> connect(){ - return make_error(); - } -}; - -error_or> create_remote(){ - auto rc = hipInit(0); - - return make_error(); -} - -template -class rpc_client { -public: - template - struct request { - std::tuple...> ids; - - error_or>> wait(); - }; -}; - -template -class rpc_server { -private: - /** - * Needs a variant ptr of all possible return types - */ - struct data_storage { - }; - -}; -} diff --git a/modules/device-hip/c++/rpc.hpp b/modules/device-hip/c++/rpc.hpp new file mode 100644 index 0000000..0bcda0c --- /dev/null +++ b/modules/device-hip/c++/rpc.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include + +namespace saw { +namespace rmt { +struct DeviceHip {}; +} + +template<> +class remote { +private: +public: + template + error_or> connect(){ + return make_error(); + } +}; + +error_or> create_remote(){ + auto rc = hipInit(0); + + return make_error(); +} + +template +class rpc_client { +public: + template + struct request { + std::tuple...> ids; + + error_or>> wait(); + }; +}; + +template +class rpc_server { +private: + /** + * Needs a variant ptr of all possible return types + */ + struct data_storage { + }; + +}; +} diff --git a/modules/io-tls/tls.h b/modules/io-tls/tls.h deleted file mode 100644 index b7d575b..0000000 --- a/modules/io-tls/tls.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include -#include - -#include -#include - -namespace saw { -class tls; - -class tls_server final : public server { -private: - own internal; - -public: - tls_server(own srv); - - conveyor> accept() override; -}; - -class tls_network final : public network { -private: - tls& tls_; - network &internal; -public: - tls_network(tls& tls_, network &network_); - - conveyor> resolve_address(const std::string &addr, uint16_t port = 0) override; - - own listen(network_address& address) override; - - conveyor> connect(network_address& address) override; - - own datagram(network_address& address) override; -}; - -/** -* tls context class. -* Provides tls network class which ensures the usage of tls encrypted connections -*/ -class tls { -private: - class impl; - own impl_; -public: - tls(); - ~tls(); - - struct version { - struct tls_1_0{}; - struct tls_1_1{}; - struct tls_1_2{}; - }; - - struct options { - public: - version version; - }; - - impl &get_impl(); -private: - options options_; -}; - -std::optional> setup_tls_network(network &network); - -} // namespace saw diff --git a/modules/io-tls/tls.hpp b/modules/io-tls/tls.hpp new file mode 100644 index 0000000..b7d575b --- /dev/null +++ b/modules/io-tls/tls.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include +#include + +#include +#include + +namespace saw { +class tls; + +class tls_server final : public server { +private: + own internal; + +public: + tls_server(own srv); + + conveyor> accept() override; +}; + +class tls_network final : public network { +private: + tls& tls_; + network &internal; +public: + tls_network(tls& tls_, network &network_); + + conveyor> resolve_address(const std::string &addr, uint16_t port = 0) override; + + own listen(network_address& address) override; + + conveyor> connect(network_address& address) override; + + own datagram(network_address& address) override; +}; + +/** +* tls context class. +* Provides tls network class which ensures the usage of tls encrypted connections +*/ +class tls { +private: + class impl; + own impl_; +public: + tls(); + ~tls(); + + struct version { + struct tls_1_0{}; + struct tls_1_1{}; + struct tls_1_2{}; + }; + + struct options { + public: + version version; + }; + + impl &get_impl(); +private: + options options_; +}; + +std::optional> setup_tls_network(network &network); + +} // namespace saw diff --git a/modules/io/io.h b/modules/io/io.h deleted file mode 100644 index b58394e..0000000 --- a/modules/io/io.h +++ /dev/null @@ -1,219 +0,0 @@ -#pragma once - -#include -#include -#include "io_helpers.h" - -#include -#include - -namespace saw { -/** - * Set of error common in io - */ -namespace err { -struct disconnected { - static constexpr std::string_view description = "Disconnected"; - static constexpr bool is_critical = true; -}; - -struct resource_busy { - static constexpr std::string_view description = "Resource busy"; - static constexpr bool is_critical = false; -}; -} -/* - * Input stream - */ -class input_stream { -public: - virtual ~input_stream() = default; - - virtual error_or read(void *buffer, size_t length) = 0; - - virtual conveyor read_ready() = 0; - - virtual conveyor on_read_disconnected() = 0; -}; - -/* - * Output stream - */ -class output_stream { -public: - virtual ~output_stream() = default; - - virtual error_or write(const void *buffer, size_t length) = 0; - - virtual conveyor write_ready() = 0; -}; - -/* - * Io stream - */ -class io_stream : public input_stream, public output_stream { -public: - virtual ~io_stream() = default; -}; - -class async_input_stream { -public: - virtual ~async_input_stream() = default; - - virtual void read(void *buffer, size_t min_length, size_t max_length) = 0; - - virtual conveyor read_done() = 0; - virtual conveyor on_read_disconnected() = 0; -}; - -class async_output_stream { -public: - virtual ~async_output_stream() = default; - - virtual void write(const void *buffer, size_t length) = 0; - - virtual conveyor write_done() = 0; -}; - -class async_io_stream final : public async_input_stream, - public async_output_stream { -private: - own stream_; - - conveyor_sink read_ready_; - conveyor_sink write_ready_; - conveyor_sink read_disconnected_; - - read_task_and_step_helper read_stepper_; - write_task_and_step_helper write_stepper_; - -public: - async_io_stream(own str); - - SAW_FORBID_COPY(async_io_stream); - SAW_FORBID_MOVE(async_io_stream); - - void read(void *buffer, size_t length, size_t max_length) override; - - conveyor read_done() override; - - conveyor on_read_disconnected() override; - - void write(const void *buffer, size_t length) override; - - conveyor write_done() override; -}; - -class server { -public: - virtual ~server() = default; - - virtual conveyor> accept() = 0; -}; - -class network_address; -/** - * Datagram class. Bound to a local address it is able to receive inbound - * datagram messages and send them as well as long as an address is provided as - * well - */ -class datagram { -public: - virtual ~datagram() = default; - - virtual error_or read(void *buffer, size_t length) = 0; - virtual conveyor read_ready() = 0; - - virtual error_or write(const void *buffer, size_t length, - network_address &dest) = 0; - virtual conveyor write_ready() = 0; -}; - -class os_network_address; -class string_network_address; - -class network_address { -public: - using child_variant = - std::variant; - - virtual ~network_address() = default; - - virtual network_address::child_variant representation() = 0; - - virtual const std::string &address() const = 0; - virtual uint16_t port() const = 0; -}; - -class os_network_address : public network_address { -public: - virtual ~os_network_address() = default; - - network_address::child_variant representation() override { return this; } -}; - -class string_network_address final : public network_address { -private: - std::string address_value_; - uint16_t port_value_; - -public: - string_network_address(const std::string &address, uint16_t port); - - const std::string &address() const override; - uint16_t port() const override; - - network_address::child_variant representation() override { return this; } -}; - -class network { -public: - virtual ~network() = default; - - /** - * Resolve the provided string and uint16 to the preferred storage method - */ - virtual conveyor> - resolve_address(const std::string &addr, uint16_t port_hint = 0) = 0; - - /** - * Parse the provided string and uint16 to the preferred storage method - * Since no dns request is made here, no async conveyors have to be used. - */ - /// @todo implement - // virtual Own parseAddress(const std::string& addr, - // uint16_t port_hint = 0) = 0; - - /** - * Set up a listener on this address - */ - virtual own listen(network_address &bind_addr) = 0; - - /** - * Connect to a remote address - */ - virtual conveyor> connect(network_address &address) = 0; - - /** - * Bind a datagram socket at this address. - */ - virtual own datagram(network_address &address) = 0; -}; - -class io_provider { -public: - virtual ~io_provider() = default; - - virtual own wrap_input_fd(int fd) = 0; - - virtual network &get_network() = 0; -}; - -struct async_io_context { - own io; - event_loop &event_loop; - event_port &event_port; -}; - -error_or setup_async_io(); -} // namespace saw diff --git a/modules/io/io.hpp b/modules/io/io.hpp new file mode 100644 index 0000000..e2022be --- /dev/null +++ b/modules/io/io.hpp @@ -0,0 +1,219 @@ +#pragma once + +#include +#include +#include "io_helpers.hpp + +#include +#include + +namespace saw { +/** + * Set of error common in io + */ +namespace err { +struct disconnected { + static constexpr std::string_view description = "Disconnected"; + static constexpr bool is_critical = true; +}; + +struct resource_busy { + static constexpr std::string_view description = "Resource busy"; + static constexpr bool is_critical = false; +}; +} +/* + * Input stream + */ +class input_stream { +public: + virtual ~input_stream() = default; + + virtual error_or read(void *buffer, size_t length) = 0; + + virtual conveyor read_ready() = 0; + + virtual conveyor on_read_disconnected() = 0; +}; + +/* + * Output stream + */ +class output_stream { +public: + virtual ~output_stream() = default; + + virtual error_or write(const void *buffer, size_t length) = 0; + + virtual conveyor write_ready() = 0; +}; + +/* + * Io stream + */ +class io_stream : public input_stream, public output_stream { +public: + virtual ~io_stream() = default; +}; + +class async_input_stream { +public: + virtual ~async_input_stream() = default; + + virtual void read(void *buffer, size_t min_length, size_t max_length) = 0; + + virtual conveyor read_done() = 0; + virtual conveyor on_read_disconnected() = 0; +}; + +class async_output_stream { +public: + virtual ~async_output_stream() = default; + + virtual void write(const void *buffer, size_t length) = 0; + + virtual conveyor write_done() = 0; +}; + +class async_io_stream final : public async_input_stream, + public async_output_stream { +private: + own stream_; + + conveyor_sink read_ready_; + conveyor_sink write_ready_; + conveyor_sink read_disconnected_; + + read_task_and_step_helper read_stepper_; + write_task_and_step_helper write_stepper_; + +public: + async_io_stream(own str); + + SAW_FORBID_COPY(async_io_stream); + SAW_FORBID_MOVE(async_io_stream); + + void read(void *buffer, size_t length, size_t max_length) override; + + conveyor read_done() override; + + conveyor on_read_disconnected() override; + + void write(const void *buffer, size_t length) override; + + conveyor write_done() override; +}; + +class server { +public: + virtual ~server() = default; + + virtual conveyor> accept() = 0; +}; + +class network_address; +/** + * Datagram class. Bound to a local address it is able to receive inbound + * datagram messages and send them as well as long as an address is provided as + * well + */ +class datagram { +public: + virtual ~datagram() = default; + + virtual error_or read(void *buffer, size_t length) = 0; + virtual conveyor read_ready() = 0; + + virtual error_or write(const void *buffer, size_t length, + network_address &dest) = 0; + virtual conveyor write_ready() = 0; +}; + +class os_network_address; +class string_network_address; + +class network_address { +public: + using child_variant = + std::variant; + + virtual ~network_address() = default; + + virtual network_address::child_variant representation() = 0; + + virtual const std::string &address() const = 0; + virtual uint16_t port() const = 0; +}; + +class os_network_address : public network_address { +public: + virtual ~os_network_address() = default; + + network_address::child_variant representation() override { return this; } +}; + +class string_network_address final : public network_address { +private: + std::string address_value_; + uint16_t port_value_; + +public: + string_network_address(const std::string &address, uint16_t port); + + const std::string &address() const override; + uint16_t port() const override; + + network_address::child_variant representation() override { return this; } +}; + +class network { +public: + virtual ~network() = default; + + /** + * Resolve the provided string and uint16 to the preferred storage method + */ + virtual conveyor> + resolve_address(const std::string &addr, uint16_t port_hint = 0) = 0; + + /** + * Parse the provided string and uint16 to the preferred storage method + * Since no dns request is made here, no async conveyors have to be used. + */ + /// @todo implement + // virtual Own parseAddress(const std::string& addr, + // uint16_t port_hint = 0) = 0; + + /** + * Set up a listener on this address + */ + virtual own listen(network_address &bind_addr) = 0; + + /** + * Connect to a remote address + */ + virtual conveyor> connect(network_address &address) = 0; + + /** + * Bind a datagram socket at this address. + */ + virtual own datagram(network_address &address) = 0; +}; + +class io_provider { +public: + virtual ~io_provider() = default; + + virtual own wrap_input_fd(int fd) = 0; + + virtual network &get_network() = 0; +}; + +struct async_io_context { + own io; + event_loop &event_loop; + event_port &event_port; +}; + +error_or setup_async_io(); +} // namespace saw diff --git a/modules/io/io_helpers.h b/modules/io/io_helpers.h deleted file mode 100644 index 761ee35..0000000 --- a/modules/io/io_helpers.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include -#include - -#include -#include - -namespace saw { -/* - * Helper classes for the specific driver implementations - */ - -/* - * Since I don't want to repeat these implementations for tls on unix systems - * and gnutls doesn't let me write or read into buffers I have to have this kind - * of strange abstraction. This may also be reusable for windows/macOS though. - */ -class input_stream; - -class read_task_and_step_helper { -public: - struct read_io_task { - void *buffer; - size_t min_length; - size_t max_length; - size_t already_read = 0; - }; - std::optional read_task; - own> read_done = nullptr; - - own> on_read_disconnect = nullptr; - -public: - void read_step(input_stream &reader); -}; - -class output_stream; - -class write_task_and_step_helper { -public: - struct write_io_task { - const void *buffer; - size_t length; - size_t already_written = 0; - }; - std::optional write_task; - own> write_done = nullptr; - -public: - void write_step(output_stream &writer); -}; -} // namespace saw diff --git a/modules/io/io_helpers.hpp b/modules/io/io_helpers.hpp new file mode 100644 index 0000000..761ee35 --- /dev/null +++ b/modules/io/io_helpers.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include +#include + +#include +#include + +namespace saw { +/* + * Helper classes for the specific driver implementations + */ + +/* + * Since I don't want to repeat these implementations for tls on unix systems + * and gnutls doesn't let me write or read into buffers I have to have this kind + * of strange abstraction. This may also be reusable for windows/macOS though. + */ +class input_stream; + +class read_task_and_step_helper { +public: + struct read_io_task { + void *buffer; + size_t min_length; + size_t max_length; + size_t already_read = 0; + }; + std::optional read_task; + own> read_done = nullptr; + + own> on_read_disconnect = nullptr; + +public: + void read_step(input_stream &reader); +}; + +class output_stream; + +class write_task_and_step_helper { +public: + struct write_io_task { + const void *buffer; + size_t length; + size_t already_written = 0; + }; + std::optional write_task; + own> write_done = nullptr; + +public: + void write_step(output_stream &writer); +}; +} // namespace saw diff --git a/modules/io_codec/io_peer.h b/modules/io_codec/io_peer.h deleted file mode 100644 index b9a4b34..0000000 --- a/modules/io_codec/io_peer.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace saw { - -template , - typename OutContainer = message_container, - typename BufferT = ring_buffer> -class streaming_io_peer { -public: - /** - * - */ - streaming_io_peer( - own>> feed, - own stream, Codec codec, BufferT in, BufferT out); - /** - * - */ - streaming_io_peer( - own>> feed, - own stream); - - /** - * Deleted copy and move constructors - */ - SAW_FORBID_COPY(streaming_io_peer); - SAW_FORBID_MOVE(streaming_io_peer); - - /** - * Send a message to the remote peer - */ - error send(heap_message_root builder); - - /** - * A phantom conveyor feeder. Meant for interfacing with other components - */ - conveyor_feeder> &feeder(); - - conveyor on_read_disconnected(); - -private: - /// @unimplemented - class peer_conveyor_feeder final - : public conveyor_feeder> { - public: - peer_conveyor_feeder( - streaming_io_peer &peer_) - : peer_{peer_} {} - - void feed(heap_message_root &&data) override { - (void)data; - } - - void fail(error &&error) override { (void)error; } - - size_t space() const override { return 0; } - - size_t queued() const override { return 0; } - - private: - streaming_io_peer &peer_; - }; - -private: - own>> - incoming_feeder_ = nullptr; - - own io_stream_; - - Codec codec_; - - BufferT in_buffer_; - BufferT out_buffer_; - - conveyor_sink sink_read_; - conveyor_sink sink_write_; - - peer_conveyor_feeder conveyor_feeder_; -}; - -/** - * Setup new streaming io peer with the provided network protocols. - * This is a convenience wrapper intended for a faster setup of this class - */ -template , - typename OutContainer = message_container, - typename BufferT = ring_buffer> -std::pair>, - conveyor>> -new_streaming_io_peer(own stream); - -} // namespace saw - -#include "io_peer.tmpl.h" diff --git a/modules/io_codec/io_peer.hpp b/modules/io_codec/io_peer.hpp new file mode 100644 index 0000000..46a7d11 --- /dev/null +++ b/modules/io_codec/io_peer.hpp @@ -0,0 +1,104 @@ +#pragma once + +#include +#include +#include +#include + +namespace saw { + +template , + typename OutContainer = message_container, + typename BufferT = ring_buffer> +class streaming_io_peer { +public: + /** + * + */ + streaming_io_peer( + own>> feed, + own stream, Codec codec, BufferT in, BufferT out); + /** + * + */ + streaming_io_peer( + own>> feed, + own stream); + + /** + * Deleted copy and move constructors + */ + SAW_FORBID_COPY(streaming_io_peer); + SAW_FORBID_MOVE(streaming_io_peer); + + /** + * Send a message to the remote peer + */ + error send(heap_message_root builder); + + /** + * A phantom conveyor feeder. Meant for interfacing with other components + */ + conveyor_feeder> &feeder(); + + conveyor on_read_disconnected(); + +private: + /// @unimplemented + class peer_conveyor_feeder final + : public conveyor_feeder> { + public: + peer_conveyor_feeder( + streaming_io_peer &peer_) + : peer_{peer_} {} + + void feed(heap_message_root &&data) override { + (void)data; + } + + void fail(error &&error) override { (void)error; } + + size_t space() const override { return 0; } + + size_t queued() const override { return 0; } + + private: + streaming_io_peer &peer_; + }; + +private: + own>> + incoming_feeder_ = nullptr; + + own io_stream_; + + Codec codec_; + + BufferT in_buffer_; + BufferT out_buffer_; + + conveyor_sink sink_read_; + conveyor_sink sink_write_; + + peer_conveyor_feeder conveyor_feeder_; +}; + +/** + * Setup new streaming io peer with the provided network protocols. + * This is a convenience wrapper intended for a faster setup of this class + */ +template , + typename OutContainer = message_container, + typename BufferT = ring_buffer> +std::pair>, + conveyor>> +new_streaming_io_peer(own stream); + +} // namespace saw + +#include "io_peer.tmpl.hpp diff --git a/modules/io_codec/io_peer.tmpl.h b/modules/io_codec/io_peer.tmpl.h deleted file mode 100644 index 880a58a..0000000 --- a/modules/io_codec/io_peer.tmpl.h +++ /dev/null @@ -1,117 +0,0 @@ -namespace saw { - -template -streaming_io_peer:: - streaming_io_peer( - own>> feed, - own str) - : streaming_io_peer{std::move(feed), std::move(str), {}, {}, {}} {} - -template -streaming_io_peer:: - streaming_io_peer( - own>> feed, - own stream, Codec codec, BufferT in, BufferT out) - : incoming_feeder_{std::move(feed)}, - io_stream_{std::move(stream)}, codec_{std::move(codec)}, - in_buffer_{std::move(in)}, out_buffer_{std::move(out)}, - sink_read_{ - io_stream_->read_done() - .then([this](size_t bytes) -> error_or { - in_buffer_.write_advance(bytes); - - if (in_buffer_.write_segment_length() == 0) { - return critical_error("Message too long"); - } - - io_stream_->read(&in_buffer_.write(), 1, - in_buffer_.write_segment_length()); - - while (true) { - auto root = heap_message_root(); - auto builder = root.build(); - - error err = codec_.template decode( - builder, in_buffer_); - if (err.is_critical()) { - return err; - } - - if (!err.failed()) { - incoming_feeder_->feed(std::move(root)); - } else { - break; - } - } - - return void_t{}; - }) - .sink([this](error err) { - incoming_feeder_->fail(err.copy_error()); - - return err; - })}, - sink_write_{io_stream_->write_done() - .then([this](size_t bytes) -> error_or { - out_buffer_.read_advance(bytes); - if (out_buffer_.readCompositeLength() > 0) { - io_stream_->write( - &out_buffer_.read(), - out_buffer_.read_segment_length()); - } - - return void_t{}; - }) - .sink()} { - io_stream_->read(&in_buffer_.write(), 1, in_buffer_.write_segment_length()); -} - -template -error streaming_io_peer::send(heap_message_root - msg) { - bool restart_write = out_buffer_.read_segment_length() == 0; - - error err = - codec_.template encode(msg.read(), out_buffer_); - if (err.failed()) { - return err; - } - - if (restart_write) { - io_stream_->write(&out_buffer_.read(), - out_buffer_.read_segment_length()); - } - - return no_error(); -} - -template -conveyor -streaming_io_peer::on_read_disconnected() { - return io_stream_->on_read_disconnected(); -} - -template -std::pair>, - conveyor>> -newstreaming_io_peer(own stream) { - auto caf = - new_conveyor_and_feeder>(); - - return {heap>( - std::move(caf.feeder), std::move(stream)), - std::move(caf.conveyor)}; -} - -} // namespace saw diff --git a/modules/io_codec/io_peer.tmpl.hpp b/modules/io_codec/io_peer.tmpl.hpp new file mode 100644 index 0000000..880a58a --- /dev/null +++ b/modules/io_codec/io_peer.tmpl.hpp @@ -0,0 +1,117 @@ +namespace saw { + +template +streaming_io_peer:: + streaming_io_peer( + own>> feed, + own str) + : streaming_io_peer{std::move(feed), std::move(str), {}, {}, {}} {} + +template +streaming_io_peer:: + streaming_io_peer( + own>> feed, + own stream, Codec codec, BufferT in, BufferT out) + : incoming_feeder_{std::move(feed)}, + io_stream_{std::move(stream)}, codec_{std::move(codec)}, + in_buffer_{std::move(in)}, out_buffer_{std::move(out)}, + sink_read_{ + io_stream_->read_done() + .then([this](size_t bytes) -> error_or { + in_buffer_.write_advance(bytes); + + if (in_buffer_.write_segment_length() == 0) { + return critical_error("Message too long"); + } + + io_stream_->read(&in_buffer_.write(), 1, + in_buffer_.write_segment_length()); + + while (true) { + auto root = heap_message_root(); + auto builder = root.build(); + + error err = codec_.template decode( + builder, in_buffer_); + if (err.is_critical()) { + return err; + } + + if (!err.failed()) { + incoming_feeder_->feed(std::move(root)); + } else { + break; + } + } + + return void_t{}; + }) + .sink([this](error err) { + incoming_feeder_->fail(err.copy_error()); + + return err; + })}, + sink_write_{io_stream_->write_done() + .then([this](size_t bytes) -> error_or { + out_buffer_.read_advance(bytes); + if (out_buffer_.readCompositeLength() > 0) { + io_stream_->write( + &out_buffer_.read(), + out_buffer_.read_segment_length()); + } + + return void_t{}; + }) + .sink()} { + io_stream_->read(&in_buffer_.write(), 1, in_buffer_.write_segment_length()); +} + +template +error streaming_io_peer::send(heap_message_root + msg) { + bool restart_write = out_buffer_.read_segment_length() == 0; + + error err = + codec_.template encode(msg.read(), out_buffer_); + if (err.failed()) { + return err; + } + + if (restart_write) { + io_stream_->write(&out_buffer_.read(), + out_buffer_.read_segment_length()); + } + + return no_error(); +} + +template +conveyor +streaming_io_peer::on_read_disconnected() { + return io_stream_->on_read_disconnected(); +} + +template +std::pair>, + conveyor>> +newstreaming_io_peer(own stream) { + auto caf = + new_conveyor_and_feeder>(); + + return {heap>( + std::move(caf.feeder), std::move(stream)), + std::move(caf.conveyor)}; +} + +} // namespace saw diff --git a/modules/io_codec/rpc.h b/modules/io_codec/rpc.h deleted file mode 100644 index 020bf96..0000000 --- a/modules/io_codec/rpc.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include - -namespace saw { -namespace rmt { -struct Network {}; -} - -template<> -class remote { -private: - std::string addr_str_; -public: - remote(std::string addr_str); - - template - conveyor> create_client(); -}; - -template