summaryrefslogtreecommitdiff
path: root/c++/codec-netcdf/netcdf.tmpl.h
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2023-11-08 14:07:58 +0100
committerClaudius "keldu" Holeksa <mail@keldu.de>2023-11-08 14:08:19 +0100
commitfeae80e5e4236654ea5a843197e05d9211869750 (patch)
tree38a69e7c498f34a857f594df6bbe5082f863f68b /c++/codec-netcdf/netcdf.tmpl.h
parentfd29f23d000db081da1976659e72a679b4ebb9c4 (diff)
codec-netcdf: Basic netcdf implementation
Diffstat (limited to 'c++/codec-netcdf/netcdf.tmpl.h')
-rw-r--r--c++/codec-netcdf/netcdf.tmpl.h106
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{};
+ }
+};
+}
+}