You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.8 KiB

#pragma once
#include "nczarrcommon.h"
#include <netcdf.h>
#include <variant>
class NCSimpleTypes: public NcZarrTypes
{
protected:
template<class VType> class ReadedData
{
using Vec = std::vector<size_t>;
private:
std::unique_ptr<VType[]> data;
public:
ReadedData() = default;
ReadedData(std::unique_ptr<VType[]>&& d): data(std::move(d)) {}
VType operator()(size_t lini) const { return data[lini]; }
};
};
class NCSimpleFunctions: public NCSimpleTypes
{
int ncid;
RetVal<std::vector<Attribute>> ReadAtts(int vid) const;
protected:
NCSimpleFunctions(): ncid(0) {}
template<class VType> RetVal<ReadedData<VType>> Read(const MString& var, const size_t* start, const size_t* count) const
{
static const MString pref = "NCSimpleFunctions::Read";
size_t ind = FindInd(var, vars);
const size_t N = vars[ind].NDim();
std::unique_ptr<VType[]> cdata;
size_t dsize = 1;
for(size_t i = 0; i < N; i++) dsize *= count[i];
cdata.reset(new VType[dsize]);
int vid;
int res = nc_inq_varid(ncid, var.Buf(), &vid);
if(res != NC_NOERR) return Error(pref, MString("nc_inq_varid error: ") + nc_strerror(res));
if constexpr(std::is_same_v<VType, float>)
res = nc_get_vara_float(ncid, vid, start, count, cdata.get());
else if constexpr(std::is_same_v<VType, double>)
res = nc_get_vara_double(ncid, vid, start, count, cdata.get());
else if constexpr(std::is_same_v<VType, int>)
res = nc_get_vara_int(ncid, vid, start, count, cdata.get());
else if constexpr(std::is_same_v<VType, long>)
res = nc_get_vara_long(ncid, vid, start, count, cdata.get());
else if constexpr(std::is_same_v<VType, long long>)
res = nc_get_vara_longlong(ncid, vid, start, count, cdata.get());
else if constexpr(std::is_same_v<VType, short>)
res = nc_get_vara_short(ncid, vid, start, count, cdata.get());
else if constexpr(std::is_same_v<VType, signed char>)
res = nc_get_vara_schar(ncid, vid, start, count, cdata.get());
else if constexpr(std::is_same_v<VType, unsigned int>)
res = nc_get_vara_uint(ncid, vid, start, count, cdata.get());
else if constexpr(std::is_same_v<VType, unsigned long long>)
res = nc_get_vara_ulonglong(ncid, vid, start, count, cdata.get());
else if constexpr(std::is_same_v<VType, unsigned short>)
res = nc_get_vara_ushort(ncid, vid, start, count, cdata.get());
else if constexpr(std::is_same_v<VType, unsigned char>)
res = nc_get_vara_ubyte(ncid, vid, start, count, cdata.get());
else
return Error(pref, "Unsupported variable type");
if(res != NC_NOERR) return Error(pref, MString("nc_get_vara error: ") + nc_strerror(res));
return ReadedData<VType>(std::move(cdata));
}
public:
~NCSimpleFunctions() { nc_close(ncid); }
Error Open(const MString& filename);
};
using NCSimple = NcZarrRead<NCSimpleFunctions>;