diff options
-rw-r--r-- | modules/codec/c++/csv.h | 140 |
1 files changed, 127 insertions, 13 deletions
diff --git a/modules/codec/c++/csv.h b/modules/codec/c++/csv.h index 1664c31..7a3a18e 100644 --- a/modules/codec/c++/csv.h +++ b/modules/codec/c++/csv.h @@ -1,8 +1,10 @@ #pragma once #include <forstio/error.h> +#include <forstio/buffer.h> #include "data.h" +#include "stream_value.h" namespace saw { namespace encode { @@ -23,7 +25,7 @@ struct csv_encode<schema::Array<T,Dim>, FromDecode> { using Schema = schema::Array<T,Dim>; - static error_or<void> encode(const data<Schema, FromDecode>& from, data<Schema, encode::Csv>& to){ + static error_or<void> encode(const data<Schema, FromDecode>& from, buffer& to){ if constexpr (is_struct<T>::value){ auto eov = csv_encode<T,FromDecode>::encode_header(to); if(eov.is_error()){ @@ -46,14 +48,96 @@ template<typename... V, string_literal... K, typename FromDecode> struct csv_encode<schema::Struct<schema::Member<V,K>...>, FromDecode> { using Schema = schema::Struct<schema::Member<V,K>...>; - static error_or<void> encode_header(const data<Schema, encode::Csv>& to){ - return make_error<err::not_implemented>(); + template<size_t i> + static error_or<void> encode_header_i(buffer& to){ + // Encode string + // + constexpr auto str_view = parameter_key_pack_type<i, K...>::literal; + + for(auto& iter : str_view.view()){ + auto eov = stream_value<schema::Int8>::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<schema::Int8>::encode(iter, to); + if(eov.is_error()){ + return eov; + } + } + return encode_header_i<i+1>(to); + } + + { + /** + * Replace this with row separator + */ + constexpr std::string_view lit = "\r\n"; + for(int8_t iter : lit){ + auto eov = stream_value<schema::Int8>::encode(iter, to); + if ( eov.is_error()){ + return eov; + } + } + } + + return make_void(); } - static error_or<void> encode(const data<Schema, FromDecode>& from, data<Schema,encode::Csv>& to){ - + static error_or<void> encode_header(buffer& to){ + return encode_header_i<0>(to); + } - return make_error<err::not_implemented>(); + template<size_t i> + static error_or<void> encode_i(const data<Schema, FromDecode>& from, buffer& to){ + constexpr auto str_view = parameter_key_pack_type<i,K...>::literal; + + { + auto eov = csv_encode<typename parameter_pack_type<i,V...>::type, FromDecode>::encode(from.template get<str_view>(), 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<schema::Int8>::encode(iter, to); + if(eov.is_error()){ + return eov; + } + } + return encode_header(to); + } + { + /** + * Replace this with row separator + */ + constexpr std::string_view lit = "\r\n"; + for(int8_t iter : lit){ + auto eov = stream_value<schema::Int8>::encode(iter, to); + if ( eov.is_error()){ + return eov; + } + } + } + + return make_void(); + } + + static error_or<void> encode(const data<Schema, FromDecode>& from, buffer& to){ + return encode_i<0>(from, to); } }; @@ -61,9 +145,14 @@ template<typename FromDecode> struct csv_encode<schema::String, FromDecode> { using Schema = schema::String; - static error_or<void> encode(const data<Schema, FromDecode>& from, data<Schema, encode::Csv>& to){ - - return make_error<err::not_implemented>(); + static error_or<void> encode(const data<Schema, FromDecode>& from, buffer& to){ + for(size_t i = 0; i < from.size(); ++i){ + auto eov = stream_value<schema::Int8>::encode(from.at(i), to); + if(eov.is_error()){ + return eov; + } + } + return make_void(); } }; @@ -71,9 +160,21 @@ template<class T, size_t N, typename FromDecode> struct csv_encode<schema::Primitive<T,N>, FromDecode> { using Schema = schema::Primitive<T,N>; - static error_or<void> encode(const data<Schema, FromDecode>& from, data<Schema, encode::Csv>& to){ - - return make_error<err::not_implemented>(); + static error_or<void> encode(const data<Schema, FromDecode>& from, buffer& to){ + std::string to_str; + + try { + to_str = std::to_string(from.get()); + }catch(const std::exception& ){ + return make_error<err::out_of_memory>(); + } + for(auto iter : to_str){ + auto eov = stream_value<schema::Int8>::encode(iter, to); + if(eov.is_error()){ + return eov; + } + } + return make_void(); } }; } @@ -81,7 +182,13 @@ struct csv_encode<schema::Primitive<T,N>, FromDecode> { template<typename Schema> class data<Schema, encode::Csv> { private: + ring_buffer buffer_; public: + data() = default; + + buffer& get_buffer(){ + return buffer_; + } }; template<typename Schema> @@ -90,8 +197,15 @@ class codec<Schema, encode::Csv> { public: template<typename FromEncode> static error_or<void> encode(const data<Schema, FromEncode>& from, data<Schema,encode::Csv>& to){ + buffer_view buff_v{to.get_buffer()}; - return make_error<err::not_implemented>(); + auto eov = impl::csv_encode<Schema, FromEncode>::encode(from, buff_v); + if(eov.is_error()){ + return eov; + } + to.get_buffer().write_advance(buff_v.write_offset()); + + return eov; } template<typename ToDecode> |