From feae80e5e4236654ea5a843197e05d9211869750 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Wed, 8 Nov 2023 14:07:58 +0100 Subject: codec-netcdf: Basic netcdf implementation --- c++/codec-netcdf/netcdf.tmpl.h | 106 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 c++/codec-netcdf/netcdf.tmpl.h (limited to 'c++/codec-netcdf/netcdf.tmpl.h') diff --git a/c++/codec-netcdf/netcdf.tmpl.h b/c++/codec-netcdf/netcdf.tmpl.h new file mode 100644 index 0000000..921c84e --- /dev/null +++ b/c++/codec-netcdf/netcdf.tmpl.h @@ -0,0 +1,106 @@ +#pragma once + +namespace saw { +namespace impl { +template +struct netcdf_is_group { + static constexpr bool value = false; +}; + +template +struct netcdf_is_group...>> { + static constexpr bool value = true; +}; + +template +struct netcdf_decode; + +template +struct netcdf_decode { + using Schema = schema::Int32; + 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 != NC_INT){ + return make_error(); + } + if(nc_dimnum != 0){ + return make_error(); + } + + int32_t val{}; + rc = nc_get_var_int(from, nc_varid, &val); + if(rc != NC_NOERR){ + return make_error(); + } + + to.set(val); + + return void_t {}; + } +}; + +template +struct netcdf_decode...>, RootSchema, 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 constexpr ((i+1) < sizeof...(T)){ + auto eov = decode_member(from, to, ncid); + 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{}; + } +}; +} +} -- cgit v1.2.3