/* * Copyright 1996, 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 */ #ifdef USE_PARALLEL #include "netcdf_par.h" #else #include "netcdf.h" #endif /* USE_PARALLEL */ /* Always needed */ #include "nc.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; /*! Hashmap-related structs. NOTE: 'data' is the dimid or varid which is non-negative. we store the dimid+1 so a valid entry will have data > 0 */ typedef struct { long data; int flags; unsigned long key; } hEntry; typedef struct s_hashmap { hEntry* table; unsigned long size; unsigned long count; } NC_hashmap; /* * 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 */ /* below gets xdr'd */ NC_string *name; nc_type type; /* the discriminant */ size_t nelems; /* length of the array */ void *xvalue; /* the actual data, in external representation */ } NC_attr; typedef struct NC_attrarray { size_t nalloc; /* number allocated >= nelems */ /* below gets xdr'd */ /* NCtype type = NC_ATTRIBUTE */ size_t nelems; /* length of the array */ NC_attr **value; } 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 */ /* below gets xdr'd */ 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 */ size_t len; /* the total length originally allocated */ off_t begin; } NC_var; typedef struct NC_vararray { size_t nalloc; /* number allocated >= nelems */ /* below gets xdr'd */ /* NCtype type = NC_VARIABLE */ size_t nelems; /* length of the array */ NC_hashmap *hashmap; NC_var **value; } NC_vararray; /* Begin defined in lookup3.c */ /* End defined in lookup3.c */ /* 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, size_t vlen_max); extern int NC_lookupvar(NC3_INFO* ncp, int varid, NC_var **varp); /* End defined in var.c */ /* defined in nc_hashmap.c */ /** Creates a new hashmap near the given size. */ extern NC_hashmap* NC_hashmapCreate(unsigned long startsize); /** Inserts a new element into the hashmap. */ extern void NC_hashmapAddDim(const NC_dimarray*, long data, const char *name); /** Removes the storage for the element of the key and returns the element. */ extern long NC_hashmapRemoveDim(const NC_dimarray*, const char *name); /** Returns the element for the key. */ extern long NC_hashmapGetDim(const NC_dimarray*, const char *name); /** Inserts a new element into the hashmap. */ extern void NC_hashmapAddVar(const NC_vararray*, long data, const char *name); /** Removes the storage for the element of the key and returns the element. */ extern long NC_hashmapRemoveVar(const NC_vararray*, const char *name); /** Returns the element for the key. */ extern long NC_hashmapGetVar(const NC_vararray*, const char *name); /** Returns the number of saved elements. */ extern unsigned long NC_hashmapCount(NC_hashmap*); /** Removes the hashmap structure. */ extern void NC_hashmapDelete(NC_hashmap*); /* end defined in nc_hashmap.c */ #define IS_RECVAR(vp) \ ((vp)->shape != NULL ? (*(vp)->shape == NC_UNLIMITED) : 0 ) #ifdef LOCKNUMREC /* * typedef SHMEM type * for whenever the SHMEM functions can handle other than shorts */ typedef unsigned short int ushmem_t; typedef short int shmem_t; #endif struct NC3_INFO { /* contains the previous NC during redef. */ NC3_INFO *old; /* flags */ #define NC_CREAT 2 /* in create phase, cleared by ncendef */ #define NC_INDEF 8 /* in define mode, cleared by ncendef */ #define NC_NSYNC 0x10 /* synchronise numrecs on change */ #define NC_HSYNC 0x20 /* synchronise whole header on change */ #define NC_NDIRTY 0x40 /* numrecs has changed */ #define NC_HDIRTY 0x80 /* header info has changed */ /* NC_NOFILL in netcdf.h, historical interface */ int flags; 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; #ifdef LOCKNUMREC /* size and named indexes for the lock array protecting NC.numrecs */ # define LOCKNUMREC_DIM 4 # define LOCKNUMREC_VALUE 0 # define LOCKNUMREC_LOCK 1 # define LOCKNUMREC_SERVING 2 # define LOCKNUMREC_BASEPE 3 /* Used on Cray T3E MPP to maintain the * integrity of numrecs for an unlimited dimension */ ushmem_t lock[LOCKNUMREC_DIM]; #endif }; #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)->flags, NC_CREAT) #define NC_indef(ncp) \ (NC_IsNew(ncp) || fIsSet((ncp)->flags, NC_INDEF)) #define set_NC_ndirty(ncp) \ fSet((ncp)->flags, NC_NDIRTY) #define NC_ndirty(ncp) \ fIsSet((ncp)->flags, NC_NDIRTY) #define set_NC_hdirty(ncp) \ fSet((ncp)->flags, NC_HDIRTY) #define NC_hdirty(ncp) \ fIsSet((ncp)->flags, NC_HDIRTY) #define NC_dofill(ncp) \ (!fIsSet((ncp)->flags, NC_NOFILL)) #define NC_doHsync(ncp) \ fIsSet((ncp)->flags, NC_HSYNC) #define NC_doNsync(ncp) \ fIsSet((ncp)->flags, NC_NSYNC) #ifndef LOCKNUMREC # 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));} #else size_t NC_get_numrecs(const NC3_INFO *nc3i); void NC_set_numrecs(NC3_INFO *nc3i, size_t nrecs); void NC_increase_numrecs(NC3_INFO *nc3i, size_t nrecs); #endif /* 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, size_t 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); /* 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_ */