summaryrefslogtreecommitdiff
path: root/modules/codec-netcdf/c++/netcdf.hpp
diff options
context:
space:
mode:
authorClaudius "keldu" Holeksa <mail@keldu.de>2024-01-23 13:12:11 +0100
committerClaudius "keldu" Holeksa <mail@keldu.de>2024-01-23 13:12:11 +0100
commit8dad985328e2183b224300aa992951131956fdb3 (patch)
treeceda3d9805335f36f571fb36585444ebdb421a02 /modules/codec-netcdf/c++/netcdf.hpp
parenta9d2025030d0a7641f4b0701bd4aff7d2db5aeb4 (diff)
core,codec-json,codec-minecraft,codec-netcdf,codec,io-tls,io,io_codec,window,window-opengl:
Renamed file endings and changed includes
Diffstat (limited to 'modules/codec-netcdf/c++/netcdf.hpp')
-rw-r--r--modules/codec-netcdf/c++/netcdf.hpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/modules/codec-netcdf/c++/netcdf.hpp b/modules/codec-netcdf/c++/netcdf.hpp
new file mode 100644
index 0000000..66d6391
--- /dev/null
+++ b/modules/codec-netcdf/c++/netcdf.hpp
@@ -0,0 +1,151 @@
+#pragma once
+
+#include <forstio/string_literal.h>
+#include <forstio/error.h>
+#include <forstio/codec/data.h>
+
+#include <netcdf.h>
+#include <netcdf_mem.h>
+
+namespace saw {
+namespace encode {
+/**
+ * Template type hint
+ */
+struct Netcdf {};
+}
+
+/**
+ * Class representing the files system netcdf file
+ */
+template<typename Schema>
+class data<Schema, encode::Netcdf> {
+private:
+ std::vector<uint8_t> buff_;
+public:
+ data() = default;
+
+ data(std::vector<uint8_t> buff):
+ buff_{std::move(buff)}
+ {}
+
+ template<size_t N>
+ data(const std::array<uint8_t, N>& arr):
+ buff_{arr.begin(), arr.end()}
+ {}
+
+ std::vector<uint8_t>& get_data() {
+ return buff_;
+ }
+
+ const std::vector<uint8_t>& get_data() const {
+ return buff_;
+ }
+};
+
+template<typename Schema>
+class codec<Schema, encode::Netcdf>{
+ static_assert(always_false<Schema,encode::Netcdf>, "NetCDF only supports Structs as a root object");
+};
+
+}
+#include "netcdf.tmpl.hpp
+namespace saw {
+
+template<typename... Vals, string_literal... Keys>
+class codec<schema::Struct<schema::Member<Vals,Keys>...>, encode::Netcdf> {
+private:
+ using Schema = schema::Struct<schema::Member<Vals,Keys>...>;
+public:
+ SAW_FORBID_COPY(codec);
+ SAW_DEFAULT_MOVE(codec);
+
+ /**
+ * Default constructor
+ */
+ codec() = default;
+
+ /**
+ * Encoder function
+ */
+ template<typename FromEncoding>
+ error_or<void> encode(const data<Schema, FromEncoding>& from, data<Schema,encode::Netcdf>& to) {
+ int rc{};
+ int ncid{};
+
+ rc = nc_create_mem("forstio_internal_write_memory", 0,/*NC_NETCDF4, */0, &ncid);
+ if(rc != NC_NOERR){
+ return make_error<err::critical>();
+ }
+
+ {
+ auto eov = impl::netcdf_encode<Schema,FromEncoding>::encode_meta(from, ncid);
+ if(eov.is_error()){
+ nc_close(ncid);
+ return eov;
+ }
+ }
+
+ rc = nc_enddef(ncid);
+ if(rc != NC_NOERR){
+ nc_close(ncid);
+ return make_error<err::critical>();
+ }
+
+ {
+ auto eov = impl::netcdf_encode<Schema,FromEncoding>::encode(from, ncid);
+ if(eov.is_error()){
+ nc_close(ncid);
+ return eov;
+ }
+ }
+
+ NC_memio nc_memio;
+ rc = nc_close_memio(ncid, &nc_memio);
+ if(rc != NC_NOERR){
+ return make_error<err::critical>();
+ }
+
+ if(!nc_memio.memory || nc_memio.size == 0){
+ return make_error<err::critical>();
+ }
+
+ try {
+ to.get_data().resize(nc_memio.size);
+ }catch(const std::exception& e){
+ (void) e;
+ return make_error<err::out_of_memory>();
+ }
+
+ for(std::size_t i = 0; i < nc_memio.size; ++i){
+ to.get_data().at(i) = static_cast<uint8_t*>(nc_memio.memory)[i];
+ }
+
+ free(nc_memio.memory);
+ nc_memio.memory = nullptr;
+
+ return void_t{};
+ }
+
+ /**
+ * Decoder function
+ */
+ template<typename ToEncoding>
+ error_or<void> decode(data<Schema, encode::Netcdf>& from_decode, data<Schema,ToEncoding>& to_decode) {
+ int ncid{};
+ int rc{};
+
+ rc = nc_open_mem("forstio_internal_read_memory", NC_NOWRITE, from_decode.get_data().size(), &from_decode.get_data()[0], &ncid);
+ if(rc != NC_NOERR){
+ // Don't know how to get the error, so fail critically.
+ return make_error<err::critical>();
+ }
+
+ auto eov = impl::netcdf_decode<Schema, ToEncoding>::decode(to_decode, ncid);
+
+ nc_close(ncid);
+
+ return eov;
+ }
+};
+}