From 3353cad0b365bc870306ccaa21f701859e68a92f Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Wed, 8 Nov 2023 16:20:32 +0100 Subject: codec-netcdf: Multidimensional arrays implemented --- c++/codec-netcdf/netcdf.tmpl.h | 123 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 111 insertions(+), 12 deletions(-) (limited to 'c++/codec-netcdf/netcdf.tmpl.h') diff --git a/c++/codec-netcdf/netcdf.tmpl.h b/c++/codec-netcdf/netcdf.tmpl.h index 921c84e..f3b36b8 100644 --- a/c++/codec-netcdf/netcdf.tmpl.h +++ b/c++/codec-netcdf/netcdf.tmpl.h @@ -2,6 +2,41 @@ 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; @@ -12,12 +47,13 @@ struct netcdf_is_group...>> { static constexpr bool value = true; }; -template +template struct netcdf_decode; -template -struct netcdf_decode { - using Schema = schema::Int32; +template +struct netcdf_decode, ToDecode> { + using Schema = schema::Primitive; + static error_or decode(data& to, int from, int nc_varid){ int rc{}; @@ -29,15 +65,15 @@ struct netcdf_decode { if(rc != NC_NOERR){ return make_error(); } - if(nc_vartype != NC_INT){ + if(nc_vartype != netcdf_primitive_id>::value){ return make_error(); } if(nc_dimnum != 0){ return make_error(); } - int32_t val{}; - rc = nc_get_var_int(from, nc_varid, &val); + typename native_data_type>::type val{}; + rc = nc_get_var(from, nc_varid, &val); if(rc != NC_NOERR){ return make_error(); } @@ -48,8 +84,71 @@ struct netcdf_decode { } }; -template -struct netcdf_decode...>, RootSchema, ToDecode> { +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 @@ -67,7 +166,7 @@ struct netcdf_decode...>, RootSchema, ToDe if(rc != NC_NOERR) { return make_error(); } - auto eov = netcdf_decode::decode(to.template get(), nc_group_id); + auto eov = netcdf_decode::decode(to.template get(), nc_group_id); if(eov.is_error()){ return eov; } @@ -78,12 +177,12 @@ struct netcdf_decode...>, RootSchema, ToDe if(rc != NC_NOERR) { return make_error(); } - auto eov = netcdf_decode::decode(to.template get(), from, nc_varid); + auto eov = netcdf_decode::decode(to.template get(), from, nc_varid); } } if constexpr ((i+1) < sizeof...(T)){ - auto eov = decode_member(from, to, ncid); + auto eov = decode_member(to, from); if(eov.is_error()){ return eov; } -- cgit v1.2.3