nc4internal.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. /** \file
  2. This header file contains the definitions of structs used to hold
  3. netCDF file metadata in memory.
  4. Copyright 2005-2011 University Corporation for Atmospheric
  5. Research/Unidata.
  6. */
  7. #ifndef _NC4INTERNAL_
  8. #define _NC4INTERNAL_
  9. #include <config.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <ctype.h>
  13. #include <stdarg.h>
  14. #include <string.h>
  15. #include <hdf5.h>
  16. #include <ncdimscale.h>
  17. #include <nc_logging.h>
  18. #ifdef USE_PARALLEL
  19. #include <netcdf_par.h>
  20. #else
  21. #define MPI_Info int
  22. #define MPI_Comm int
  23. #include <netcdf.h>
  24. #endif /* USE_PARALLEL */
  25. #include <netcdf_f.h>
  26. #ifdef USE_HDF4
  27. #include <mfhdf.h>
  28. #endif
  29. #define FILE_ID_MASK (0xffff0000)
  30. #define GRP_ID_MASK (0x0000ffff)
  31. #define ID_SHIFT (16)
  32. typedef enum {GET, PUT} NC_PG_T;
  33. typedef enum {VAR, DIM, ATT} NC_OBJ_T;
  34. #define NC_MAX_HDF5_NAME (NC_MAX_NAME + 10)
  35. #define NC_V2_ERR (-1)
  36. /* The name of the root group. */
  37. #define NC_GROUP_NAME "/"
  38. #define MEGABYTE 1048576
  39. /*
  40. * limits of the external representation
  41. */
  42. #define X_SCHAR_MIN (-128)
  43. #define X_SCHAR_MAX 127
  44. #define X_UCHAR_MAX 255U
  45. #define X_SHORT_MIN (-32768)
  46. #define X_SHRT_MIN X_SHORT_MIN /* alias compatible with limits.h */
  47. #define X_SHORT_MAX 32767
  48. #define X_SHRT_MAX X_SHORT_MAX /* alias compatible with limits.h */
  49. #define X_USHORT_MAX 65535U
  50. #define X_USHRT_MAX X_USHORT_MAX /* alias compatible with limits.h */
  51. #define X_INT_MIN (-2147483647-1)
  52. #define X_INT_MAX 2147483647
  53. #define X_LONG_MIN X_INT_MIN
  54. #define X_LONG_MAX X_INT_MAX
  55. #define X_UINT_MAX 4294967295U
  56. #ifdef WIN32 /* Windows, of course, has to be a *little* different. */
  57. #define X_FLOAT_MAX 3.402823466e+38f
  58. #else
  59. #define X_FLOAT_MAX 3.40282347e+38f
  60. #endif /* WIN32 */
  61. #define X_FLOAT_MIN (-X_FLOAT_MAX)
  62. #define X_DOUBLE_MAX 1.7976931348623157e+308
  63. #define X_DOUBLE_MIN (-X_DOUBLE_MAX)
  64. /* These have to do with creating chuncked datasets in HDF5. */
  65. #define NC_HDF5_UNLIMITED_DIMSIZE (0)
  66. #define NC_HDF5_CHUNKSIZE_FACTOR (10)
  67. #define NC_HDF5_MIN_CHUNK_SIZE (2)
  68. #define NC_EMPTY_SCALE "NC_EMPTY_SCALE"
  69. /* This is an attribute I had to add to handle multidimensional
  70. * coordinate variables. */
  71. #define COORDINATES "_Netcdf4Coordinates"
  72. #define COORDINATES_LEN (NC_MAX_NAME * 5)
  73. /* This is used when the user defines a non-coordinate variable with
  74. * same name as a dimension. */
  75. #define NON_COORD_PREPEND "_nc4_non_coord_"
  76. /* An attribute in the HDF5 root group of this name means that the
  77. * file must follow strict netCDF classic format rules. */
  78. #define NC3_STRICT_ATT_NAME "_nc3_strict"
  79. /* If this attribute is present on a dimscale variable, use the value
  80. * as the netCDF dimid. */
  81. #define NC_DIMID_ATT_NAME "_Netcdf4Dimid"
  82. /* This is a struct to handle the dim metadata. */
  83. typedef struct NC_DIM_INFO
  84. {
  85. char *name;
  86. size_t len;
  87. int dimid;
  88. int unlimited;
  89. int extended;
  90. struct NC_DIM_INFO *next;
  91. struct NC_DIM_INFO *prev;
  92. hid_t hdf_dimscaleid;
  93. char *old_name; /* only used to rename dim */
  94. int dirty;
  95. unsigned char coord_var_in_grp;
  96. struct NC_VAR_INFO *coord_var; /* The coord var, if it exists. */
  97. int too_long; /* True if len it too big to fit in local size_t. */
  98. } NC_DIM_INFO_T;
  99. typedef struct NC_ATT_INFO
  100. {
  101. int len;
  102. char *name;
  103. struct NC_ATT_INFO *next;
  104. struct NC_ATT_INFO *prev;
  105. int dirty;
  106. int created;
  107. nc_type xtype;
  108. hid_t native_typeid;
  109. int attnum;
  110. void *data;
  111. nc_vlen_t *vldata; /* only used for vlen */
  112. char **stdata; /* only for string type. */
  113. int class;
  114. } NC_ATT_INFO_T;
  115. /* This is a struct to handle the var metadata. */
  116. typedef struct NC_VAR_INFO
  117. {
  118. char *name;
  119. char *hdf5_name; /* used if different from name */
  120. int ndims;
  121. int *dimids;
  122. NC_DIM_INFO_T **dim;
  123. int varid;
  124. int natts;
  125. struct NC_VAR_INFO *next;
  126. struct NC_VAR_INFO *prev;
  127. int dirty;
  128. int created;
  129. int written_to;
  130. int *dimscale_attached;
  131. struct NC_TYPE_INFO *type_info;
  132. nc_type xtype;
  133. hid_t hdf_datasetid;
  134. NC_ATT_INFO_T *att;
  135. int no_fill;
  136. void *fill_value;
  137. size_t *chunksizes;
  138. int contiguous;
  139. int parallel_access;
  140. int dimscale;
  141. HDF5_OBJID_T *dimscale_hdf5_objids;
  142. int deflate;
  143. int deflate_level;
  144. int shuffle;
  145. int fletcher32;
  146. int options_mask;
  147. int pixels_per_block;
  148. size_t chunk_cache_size, chunk_cache_nelems;
  149. float chunk_cache_preemption;
  150. /* Stuff below is for hdf4 files. */
  151. int sdsid;
  152. int hdf4_data_type;
  153. /* Stuff below for diskless data files. */
  154. void *diskless_data;
  155. } NC_VAR_INFO_T;
  156. typedef struct NC_FIELD_INFO
  157. {
  158. struct NC_FIELD_INFO *next;
  159. struct NC_FIELD_INFO *prev;
  160. nc_type nctype;
  161. hid_t hdf_typeid;
  162. hid_t native_typeid;
  163. size_t offset;
  164. char *name;
  165. int fieldid;
  166. int ndims;
  167. int *dim_size;
  168. } NC_FIELD_INFO_T;
  169. typedef struct NC_ENUM_MEMBER_INFO
  170. {
  171. struct NC_ENUM_MEMBER_INFO *next;
  172. struct NC_ENUM_MEMBER_INFO *prev;
  173. char *name;
  174. void *value;
  175. } NC_ENUM_MEMBER_INFO_T;
  176. typedef struct NC_TYPE_INFO
  177. {
  178. struct NC_TYPE_INFO *next;
  179. struct NC_TYPE_INFO *prev;
  180. nc_type nc_typeid;
  181. hid_t hdf_typeid;
  182. hid_t native_typeid;
  183. size_t size;
  184. int committed; /* What the pig is, but the hen isn't, at breakfast. */
  185. char *name;
  186. int class; /* NC_VLEN, NC_COMPOUND, NC_OPAQUE, or NC_ENUM */
  187. int num_enum_members;
  188. NC_ENUM_MEMBER_INFO_T *enum_member;
  189. NC_FIELD_INFO_T *field; /* Used for compound types. */
  190. int num_fields;
  191. nc_type base_nc_type; /* for VLEN and ENUM only */
  192. hid_t base_hdf_typeid; /* for VLEN only */
  193. int close_hdf_typeid; /* True when hdf_typeid must be H5Tclosed. */
  194. int endianness;
  195. } NC_TYPE_INFO_T;
  196. /* This holds information for one group. Groups reproduce with
  197. * parthenogenesis. */
  198. typedef struct NC_GRP_INFO
  199. {
  200. int nc_grpid;
  201. struct NC_GRP_INFO *parent;
  202. struct NC_GRP_INFO *children;
  203. struct NC_GRP_INFO *next; /* points to siblings */
  204. struct NC_GRP_INFO *prev; /* points to siblings */
  205. NC_VAR_INFO_T *var;
  206. NC_DIM_INFO_T *dim;
  207. NC_ATT_INFO_T *att;
  208. int nvars;
  209. int ndims;
  210. int natts;
  211. struct NC_FILE_INFO *file;
  212. char *name;
  213. hid_t hdf_grpid;
  214. NC_TYPE_INFO_T *type;
  215. } NC_GRP_INFO_T;
  216. /* These constants apply to the cmode parameter in the
  217. * HDF5_FILE_INFO_T defined below. */
  218. #define NC_CREAT 2 /* in create phase, cleared by ncendef */
  219. #define NC_INDEF 8 /* in define mode, cleared by ncendef */
  220. #define NC_NSYNC 0x10 /* synchronise numrecs on change */
  221. #define NC_HSYNC 0x20 /* synchronise whole header on change */
  222. #define NC_NDIRTY 0x40 /* numrecs has changed */
  223. #define NC_HDIRTY 0x80 /* header info has changed */
  224. /* This is the metadata we need to keep track of for each
  225. netcdf-4/HDF5 file. */
  226. typedef struct
  227. {
  228. hid_t hdfid;
  229. int flags;
  230. int cmode;
  231. int nvars;
  232. int ndims;
  233. int natts;
  234. int parallel; /* true if file is open for parallel access */
  235. int redef;
  236. char *path;
  237. int fill_mode;
  238. int no_write; /* true if nc_open has mode NC_NOWRITE. */
  239. NC_GRP_INFO_T *root_grp;
  240. short next_nc_grpid;
  241. NC_TYPE_INFO_T *type;
  242. int next_typeid;
  243. int next_dimid;
  244. int ignore_creationorder;
  245. int hdf4;
  246. int sdid;
  247. } NC_HDF5_FILE_INFO_T;
  248. /* In the nc_file array there will be one entry for each open file.*/
  249. /* There's an external ncid (ext_ncid) and an internal ncid
  250. * (int_ncid). The ext_ncid is the ncid returned to the user. If
  251. * the user has opened or created a netcdf-4 file, then the
  252. * ext_ncid is the same as the int_ncid. If he has opened or
  253. * created a netcdf-3 file ext_ncid (which the user sees) is
  254. * different from the int_ncid, which is the ncid returned by the
  255. * netcdf-3 layer, which insists on inventing its own ncids,
  256. * regardless of what is already in use due to previously opened
  257. * netcdf-4 files. The ext_ncid contains the ncid for the root
  258. * group (i.e. group zero). */
  259. /* Warning: fields from BEGIN COMMON to END COMMON must be same for:
  260. 1. NCcommon (include/ncdispatch.h)
  261. 2. NC (libsrc/nc.h)
  262. 3. NC_FILE_INFO (libsrc4/nc4internal.h)
  263. 4. whatever libdiskless uses
  264. */
  265. typedef struct NC_FILE_INFO
  266. {
  267. /*BEGIN COMMON*/
  268. int ext_ncid;
  269. int int_ncid;
  270. struct NC_Dispatch* dispatch;
  271. void* dispatchdata;
  272. char* path;
  273. int substrate;
  274. /*END COMMON*/
  275. #ifdef USE_PNETCDF
  276. /* pnetcdf_file will be true if the file is created/opened with the
  277. * parallel-netcdf library. pnetcdf_access_mode keeps track of
  278. * whether independpent or collective mode is
  279. * desired. pnetcdf_ndims keeps track of how many dims each var
  280. * has, which I need to know to convert start, count, and stride
  281. * arrays from size_t to MPI_Offset. (I can't use an inq function
  282. * to find out the number of dims, because these are collective in
  283. * pnetcdf.) */
  284. int pnetcdf_file;
  285. int pnetcdf_access_mode;
  286. int pnetcdf_ndims[NC_MAX_VARS];
  287. #endif /* USE_PNETCDF */
  288. /* The nc4_info pointer will remain NULL for netcdf3 files,
  289. * otherwise it points to information about the netcdf-4 file. */
  290. NC_HDF5_FILE_INFO_T *nc4_info;
  291. } NC_FILE_INFO_T;
  292. /* These functions only use the netcdf API calls, so they will work on
  293. both new format and old format files. */
  294. /*int copy_dataset(int ncid_in, int ncid_out);*/
  295. /* These functions convert beteen netcdf and HDF5 types. */
  296. int nc4_get_typelen_mem(NC_HDF5_FILE_INFO_T *h5, nc_type xtype,
  297. int is_long, size_t *len);
  298. int nc4_convert_type(const void *src, void *dest,
  299. const nc_type src_type, const nc_type dest_type,
  300. const size_t len, int *range_error,
  301. const void *fill_value, int strict_nc3, int src_long,
  302. int dest_long);
  303. /* These functions do HDF5 things. */
  304. int nc4_open_var_grp2(NC_GRP_INFO_T *grp, int varid, hid_t *dataset);
  305. int pg_var(NC_PG_T pg, NC_FILE_INFO_T *nc, int ncid, int varid, nc_type xtype, int is_long,
  306. void *ip);
  307. int nc4_pg_var1(NC_PG_T pg, NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *indexp,
  308. nc_type xtype, int is_long, void *ip);
  309. int nc4_put_vara(NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *startp,
  310. const size_t *countp, nc_type xtype, int is_long, void *op);
  311. int nc4_get_vara(NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *startp,
  312. const size_t *countp, nc_type xtype, int is_long, void *op);
  313. int nc4_pg_varm(NC_PG_T pg, NC_FILE_INFO_T *nc, int ncid, int varid, const size_t *startp,
  314. const size_t *countp, const ptrdiff_t *stridep,
  315. const ptrdiff_t *imapp, nc_type xtype, int is_long, void *op);
  316. int nc4_rec_match_dimscales(NC_GRP_INFO_T *grp);
  317. int nc4_rec_write_metadata(NC_GRP_INFO_T *grp);
  318. int nc4_rec_write_types(NC_GRP_INFO_T *grp);
  319. int nc4_enddef_netcdf4_file(NC_HDF5_FILE_INFO_T *h5);
  320. int nc4_reopen_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var);
  321. int nc4_adjust_var_cache(NC_GRP_INFO_T *grp, NC_VAR_INFO_T * var);
  322. /* The following functions manipulate the in-memory linked list of
  323. metadata, without using HDF calls. */
  324. int nc4_find_nc_grp_h5(int ncid, NC_FILE_INFO_T **nc, NC_GRP_INFO_T **grp,
  325. NC_HDF5_FILE_INFO_T **h5);
  326. int nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_HDF5_FILE_INFO_T **h5);
  327. int nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp);
  328. NC_GRP_INFO_T *nc4_find_nc_grp(int ncid);
  329. NC_GRP_INFO_T *nc4_rec_find_grp(NC_GRP_INFO_T *start_grp, int target_nc_grpid);
  330. NC_FILE_INFO_T *nc4_find_nc_file(int ncid);
  331. int nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim, NC_GRP_INFO_T **dim_grp);
  332. int nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len);
  333. int nc4_find_type(NC_HDF5_FILE_INFO_T *h5, int typeid, NC_TYPE_INFO_T **type);
  334. NC_TYPE_INFO_T *nc4_rec_find_nc_type(NC_GRP_INFO_T *start_grp, hid_t target_nc_typeid);
  335. NC_TYPE_INFO_T *nc4_rec_find_hdf_type(NC_GRP_INFO_T *start_grp, hid_t target_hdf_typeid);
  336. NC_TYPE_INFO_T *nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name);
  337. NC_TYPE_INFO_T *nc4_rec_find_equal_type(NC_GRP_INFO_T *start_grp, int ncid1, NC_TYPE_INFO_T *type);
  338. int nc4_find_nc_att(int ncid, int varid, const char *name, int attnum,
  339. NC_ATT_INFO_T **att);
  340. int nc4_find_g_var_nc(NC_FILE_INFO_T *nc, int ncid, int varid,
  341. NC_GRP_INFO_T **grp, NC_VAR_INFO_T **var);
  342. int nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum,
  343. NC_ATT_INFO_T **att);
  344. int nc4_get_hdf_typeid(NC_HDF5_FILE_INFO_T *h5, nc_type xtype,
  345. hid_t *hdf_typeid, int endianness);
  346. /*int var_info_nc(NC_PG_T pg, hid_t dataset, NC_VAR_INFO_T *var_info);*/
  347. /* These list functions add and delete vars, atts, and files. */
  348. int nc4_file_list_add(NC_FILE_INFO_T**, struct NC_Dispatch*);
  349. void nc4_file_list_free(void);
  350. int nc4_nc4f_list_add(NC_FILE_INFO_T *nc, const char *path, int mode);
  351. int nc4_var_list_add(NC_VAR_INFO_T **list, NC_VAR_INFO_T **var);
  352. int nc4_dim_list_add(NC_DIM_INFO_T **list);
  353. int nc4_dim_list_del(NC_DIM_INFO_T **list, NC_DIM_INFO_T *dim);
  354. int nc4_att_list_add(NC_ATT_INFO_T **list);
  355. int nc4_type_list_add(NC_TYPE_INFO_T **list, NC_TYPE_INFO_T **new_type);
  356. int nc4_field_list_add(NC_FIELD_INFO_T **list, int fieldid, const char *name,
  357. size_t offset, hid_t field_hdf_typeid, hid_t native_typeid,
  358. nc_type xtype, int ndims, const int *dim_sizesp);
  359. void nc4_file_list_del(NC_FILE_INFO_T *nc);
  360. int nc4_att_list_del(NC_ATT_INFO_T **list, NC_ATT_INFO_T *att);
  361. int nc4_grp_list_add(NC_GRP_INFO_T **list, int new_nc_grpid, NC_GRP_INFO_T *parent_grp,
  362. NC_FILE_INFO_T *nc, char *name, NC_GRP_INFO_T **grp);
  363. int nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp);
  364. int nc4_enum_member_add(NC_ENUM_MEMBER_INFO_T **list, size_t size,
  365. const char *name, const void *value);
  366. int NC_check_name(const char *name);
  367. /* Check and normalize names. */
  368. int nc4_check_name(const char *name, char *norm_name);
  369. int nc4_normalize_name(const char *name, char *norm_name);
  370. /* Check for name collisions. */
  371. int nc4_check_dup_name(NC_GRP_INFO_T *grp, char *norm_name);
  372. /* Insert and read one element into an already allocated vlen array
  373. * element (this is for F77). */
  374. /*int nc_put_vlen_element(int ncid, int typeid, void *vlen_element, size_t len, const void *data);
  375. int nc_get_vlen_element(int ncid, int typeid, const void *vlen_element, size_t *len, void *data);*/
  376. /* This is only included if --enable-logging is used for configure; it
  377. prints info about the metadata to stderr. */
  378. #ifdef LOGGING
  379. int log_metadata_nc(NC_FILE_INFO_T *nc);
  380. #endif
  381. #endif /* _NETCDF4_ */