/* * Copyright 2018, University Corporation for Atmospheric Research * See netcdf/COPYRIGHT file for copying and redistribution conditions. */ #ifndef _NC3INTERNAL_ #define _NC3INTERNAL_ /* * netcdf library 'private' data structures, objects and interfaces */ #include "config.h" #include /* size_t */ #ifndef HAVE_STDINT_H # include "pstdint.h" /* attempts to define uint32_t etc portably */ #else # include #endif /* HAVE_STDINT_H */ #include /* off_t */ #include "netcdf.h" #ifdef USE_PARALLEL #include "netcdf_par.h" #endif /* USE_PARALLEL */ /* Always needed */ #include "nc.h" #include "nchashmap.h" #ifndef NC_ARRAY_GROWBY #define NC_ARRAY_GROWBY 4 #endif /* * The extern size of an empty * netcdf version 1 file. * The initial value of ncp->xsz. */ /* For classic */ #define MIN_NC3_XSZ 32 /* For cdf5 */ #define MIN_NC5_XSZ 48 /* Forward */ struct ncio; typedef struct NC3_INFO NC3_INFO; /* * The internal data types */ typedef enum { NC_UNSPECIFIED = 0, /* future NC_BITFIELD = 7, */ /* NC_STRING = 8, */ NC_DIMENSION = 10, NC_VARIABLE = 11, NC_ATTRIBUTE = 12 } NCtype; /* * NC dimension structure */ typedef struct { /* all xdr'd */ NC_string* name; size_t size; } NC_dim; typedef struct NC_dimarray { size_t nalloc; /* number allocated >= nelems */ /* below gets xdr'd */ /* NCtype type = NC_DIMENSION */ size_t nelems; /* length of the array */ NC_hashmap *hashmap; NC_dim **value; } NC_dimarray; /* Begin defined in dim.c */ extern void free_NC_dim(NC_dim *dimp); extern NC_dim * new_x_NC_dim(NC_string *name); extern int find_NC_Udim(const NC_dimarray *ncap, NC_dim **dimpp); /* dimarray */ extern void free_NC_dimarrayV0(NC_dimarray *ncap); extern void free_NC_dimarrayV(NC_dimarray *ncap); extern int dup_NC_dimarrayV(NC_dimarray *ncap, const NC_dimarray *ref); extern NC_dim * elem_NC_dimarray(const NC_dimarray *ncap, size_t elem); /* End defined in dim.c */ /* * NC attribute */ typedef struct { size_t xsz; /* amount of space at xvalue */ /* begin xdr */ NC_string *name; nc_type type; /* the discriminant */ size_t nelems; /* length of the array */ void *xvalue; /* the actual data, in external representation */ /* end xdr */ } NC_attr; typedef struct NC_attrarray { size_t nalloc; /* number allocated >= nelems */ /* begin xdr */ /* NCtype type = NC_ATTRIBUTE */ size_t nelems; /* length of the array */ NC_attr **value; /* end xdr */ } NC_attrarray; /* Begin defined in attr.c */ extern void free_NC_attr(NC_attr *attrp); extern NC_attr * new_x_NC_attr( NC_string *strp, nc_type type, size_t nelems); extern NC_attr ** NC_findattr(const NC_attrarray *ncap, const char *name); /* attrarray */ extern void free_NC_attrarrayV0(NC_attrarray *ncap); extern void free_NC_attrarrayV(NC_attrarray *ncap); extern int dup_NC_attrarrayV(NC_attrarray *ncap, const NC_attrarray *ref); extern NC_attr * elem_NC_attrarray(const NC_attrarray *ncap, size_t elem); /* End defined in attr.c */ /* * NC variable: description and data */ typedef struct NC_var { size_t xsz; /* xszof 1 element */ size_t *shape; /* compiled info: dim->size of each dim */ off_t *dsizes; /* compiled info: the right to left product of shape */ /* begin xdr */ NC_string* name; /* next two: formerly NC_iarray *assoc */ /* user definition */ size_t ndims; /* assoc->count */ int *dimids; /* assoc->value */ NC_attrarray attrs; nc_type type; /* the discriminant */ long long len; /* the total length originally allocated */ off_t begin; /* end xdr */ int no_fill; /* whether fill mode is ON or OFF */ } NC_var; typedef struct NC_vararray { size_t nalloc; /* number allocated >= nelems */ /* begin xdr */ /* NCtype type = NC_VARIABLE */ size_t nelems; /* length of the array */ NC_hashmap *hashmap; NC_var **value; } NC_vararray; /* Begin defined in var.c */ extern void free_NC_var(NC_var *varp); extern NC_var * new_x_NC_var( NC_string *strp, size_t ndims); /* vararray */ extern void free_NC_vararrayV0(NC_vararray *ncap); extern void free_NC_vararrayV(NC_vararray *ncap); extern int dup_NC_vararrayV(NC_vararray *ncap, const NC_vararray *ref); extern int NC_var_shape(NC_var *varp, const NC_dimarray *dims); extern int NC_findvar(const NC_vararray *ncap, const char *name, NC_var **varpp); extern int NC_check_vlen(NC_var *varp, long long vlen_max); extern int NC_lookupvar(NC3_INFO* ncp, int varid, NC_var **varp); /* End defined in var.c */ #define IS_RECVAR(vp) \ ((vp)->shape != NULL ? (*(vp)->shape == NC_UNLIMITED) : 0 ) struct NC3_INFO { /* contains the previous NC during redef. */ NC3_INFO *old; int flags; /* mode flags */ int state; /* state transitions flags */ # define NC_CREAT 0x1 /* in create phase, cleared by ncendef */ # define NC_INDEF 0x2 /* in define mode, cleared by ncendef */ # define NC_NSYNC 0x4 /* synchronise numrecs on change */ # define NC_HSYNC 0x8 /* synchronise whole header on change */ # define NC_NDIRTY 0x10 /* numrecs has changed */ # define NC_HDIRTY 0x20 /* header info has changed */ /* NC_NOFILL defined in netcdf.h, historical interface */ #if 0 # define NC_NOFILL 0x100 /**< Argument to nc_set_fill() to turn off filling of data. */ #endif struct ncio* nciop; size_t chunk; /* largest extent this layer will request from ncio->get() */ size_t xsz; /* external size of this header, == var[0].begin */ off_t begin_var; /* position of the first (non-record) var */ off_t begin_rec; /* position of the first 'record' */ /* Don't constrain maximum size of record unnecessarily */ #if SIZEOF_OFF_T > SIZEOF_SIZE_T off_t recsize; /* length of 'record' */ #else size_t recsize; /* length of 'record' */ #endif /* below gets xdr'd */ size_t numrecs; /* number of 'records' allocated */ NC_dimarray dims; NC_attrarray attrs; NC_vararray vars; }; #define NC_readonly(ncp) \ (!fIsSet((ncp)->nciop->ioflags, NC_WRITE)) #define NC_set_readonly(ncp) \ fClr((ncp)->flags, NC_WRITE) #define NC_IsNew(ncp) \ fIsSet((ncp)->state, NC_CREAT) #define NC_indef(ncp) \ (NC_IsNew(ncp) || fIsSet((ncp)->state, NC_INDEF)) #define set_NC_ndirty(ncp) \ fSet((ncp)->state, NC_NDIRTY) #define NC_ndirty(ncp) \ fIsSet((ncp)->state, NC_NDIRTY) #define set_NC_hdirty(ncp) \ fSet((ncp)->state, NC_HDIRTY) #define NC_hdirty(ncp) \ fIsSet((ncp)->state, NC_HDIRTY) #define NC_dofill(ncp) \ (!fIsSet((ncp)->state, NC_NOFILL)) #define NC_doHsync(ncp) \ fIsSet((ncp)->state, NC_HSYNC) #define NC_doNsync(ncp) \ fIsSet((ncp)->state, NC_NSYNC) # define NC_get_numrecs(nc3i) \ ((nc3i)->numrecs) # define NC_set_numrecs(nc3i, nrecs) \ {(nc3i)->numrecs = (nrecs);} # define NC_increase_numrecs(nc3i, nrecs) \ {if((nrecs) > (nc3i)->numrecs) ((nc3i)->numrecs = (nrecs));} /* Begin defined in nc.c */ extern int nc3_cktype(int mode, nc_type datatype); extern size_t ncx_howmany(nc_type type, size_t xbufsize); extern int read_numrecs(NC3_INFO* ncp); extern int write_numrecs(NC3_INFO* ncp); extern int NC_sync(NC3_INFO* ncp); extern int NC_calcsize(const NC3_INFO* ncp, off_t *filesizep); extern int NC3_inq_default_fill_value(int xtype, void *fillp); extern int NC3_inq_var_fill(const NC_var *varp, void *fill_value); /* End defined in nc.c */ /* Begin defined in v1hpg.c */ extern size_t ncx_len_NC(const NC3_INFO* ncp, size_t sizeof_off_t); extern int ncx_put_NC(const NC3_INFO* ncp, void **xpp, off_t offset, size_t extent); extern int nc_get_NC(NC3_INFO* ncp); /* End defined in v1hpg.c */ /* Begin defined in putget.c */ extern int fill_NC_var(NC3_INFO* ncp, const NC_var *varp, long long varsize, size_t recno); extern int nc_inq_rec(int ncid, size_t *nrecvars, int *recvarids, size_t *recsizes); extern int nc_get_rec(int ncid, size_t recnum, void **datap); extern int nc_put_rec(int ncid, size_t recnum, void *const *datap); /* End defined in putget.c */ extern int NC_check_vlens(NC3_INFO *ncp); extern int NC_check_voffs(NC3_INFO *ncp); /* Define accessors for the dispatchdata */ #define NC3_DATA(nc) ((NC3_INFO*)(nc)->dispatchdata) #define NC3_DATA_SET(nc,data) ((nc)->dispatchdata = (void*)(data)) #endif /* _NC3INTERNAL_ */