diff options
author | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-11-08 14:07:58 +0100 |
---|---|---|
committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2023-11-08 14:08:19 +0100 |
commit | feae80e5e4236654ea5a843197e05d9211869750 (patch) | |
tree | 38a69e7c498f34a857f594df6bbe5082f863f68b /c++/codec-netcdf/netcdf.tmpl.h | |
parent | fd29f23d000db081da1976659e72a679b4ebb9c4 (diff) |
codec-netcdf: Basic netcdf implementation
Diffstat (limited to 'c++/codec-netcdf/netcdf.tmpl.h')
-rw-r--r-- | c++/codec-netcdf/netcdf.tmpl.h | 106 |
1 files changed, 106 insertions, 0 deletions
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<typename Schema> +struct netcdf_is_group { + static constexpr bool value = false; +}; + +template<typename... T, string_literal... Lits> +struct netcdf_is_group<schema::Struct<schema::Member<T,Lits>...>> { + static constexpr bool value = true; +}; + +template<typename Schema, typename RootSchema, typename ToEncode> +struct netcdf_decode; + +template<typename RootSchema, typename ToDecode> +struct netcdf_decode<schema::Int32, RootSchema, ToDecode> { + using Schema = schema::Int32; + static error_or<void> decode(data<Schema, ToDecode>& to, int from, int nc_varid){ + int rc{}; + + nc_type nc_vartype{}; + int nc_dimnum{}; + std::array<int,NC_MAX_VAR_DIMS> 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<err::critical>(); + } + if(nc_vartype != NC_INT){ + return make_error<err::critical>(); + } + if(nc_dimnum != 0){ + return make_error<err::critical>(); + } + + int32_t val{}; + rc = nc_get_var_int(from, nc_varid, &val); + if(rc != NC_NOERR){ + return make_error<err::critical>(); + } + + to.set(val); + + return void_t {}; + } +}; + +template<typename... T, string_literal... Lits, typename RootSchema, typename ToDecode> +struct netcdf_decode<schema::Struct<schema::Member<T,Lits>...>, RootSchema, ToDecode> { + using Schema = schema::Struct<schema::Member<T,Lits>...>; + + template<std::size_t i> + static error_or<void> decode_member(data<Schema,ToDecode>& to, int from){ + using Type = typename parameter_pack_type<i,T...>::type; + constexpr string_literal Literal = parameter_key_pack_type<i, Lits...>::literal; + { + /** + * We have to ask for the internal id of the netcdf structure + */ + if constexpr (netcdf_is_group<Type>::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<err::critical>(); + } + auto eov = netcdf_decode<Type, RootSchema, ToDecode>::decode(to.template get<Literal>(), 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<err::critical>(); + } + auto eov = netcdf_decode<Type, RootSchema, ToDecode>::decode(to.template get<Literal>(), from, nc_varid); + } + + } + if constexpr ((i+1) < sizeof...(T)){ + auto eov = decode_member<i+1>(from, to, ncid); + if(eov.is_error()){ + return eov; + } + } + + return void_t{}; + } + + + static error_or<void> decode(data<Schema, ToDecode>& to, int from){ + if constexpr (sizeof...(T) > 0){ + auto eov = decode_member<0>(to, from); + return eov; + } + + return void_t{}; + } +}; +} +} |