1 /* Copyright 2018-2018 University Corporation for Atmospheric 2 Research/Unidata. */ 3 /** 4 * @file 5 * @internal This header file contains macros, types and prototypes 6 * used to build and manipulate the netCDF metadata model. 7 * 8 * @author Ed Hartnett, Dennis Heimbigner, Ward Fisher 9 */ 10 11 #ifndef _NC4INTERNAL_ 12 #define _NC4INTERNAL_ 13 #include "netcdf.h" 14 15 #include "config.h" 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <ctype.h> 19 #include <string.h> 20 21 #include "nc_logging.h" 22 #include "ncindex.h" 23 #include "nc_provenance.h" 24 #include "nchashmap.h" 25 26 #include "netcdf_f.h" 27 #include "netcdf_mem.h" 28 #include "netcdf_filter.h" 29 #ifdef USE_PARALLEL 30 #include "netcdf_par.h" 31 #endif /* USE_PARALLEL */ 32 33 /* Always needed */ 34 #include "nc.h" 35 36 /** The file ID is stored in the first two bytes of ncid. */ 37 #define FILE_ID_MASK (0xffff0000) 38 39 /** The group ID is stored in the last two bytes of ncid. */ 40 #define GRP_ID_MASK (0x0000ffff) 41 42 /** File and group IDs are each 16 bits of the ncid. */ 43 #define ID_SHIFT (16) 44 45 /* typedef enum {GET, PUT} NC_PG_T; */ 46 /** These are the different objects that can be in our hash-lists. */ 47 typedef enum {NCNAT, NCVAR, NCDIM, NCATT, NCTYP, NCFLD, NCGRP, NCFIL} NC_SORT; 48 49 /** The netCDF V2 error code. */ 50 #define NC_V2_ERR (-1) 51 52 /** The name of the root group. */ 53 #define NC_GROUP_NAME "/" 54 55 /** One mega-byte. */ 56 #define MEGABYTE 1048576 57 58 /** The HDF5 ID for the szip filter. */ 59 #define HDF5_FILTER_SZIP 4 60 61 #define X_SCHAR_MIN (-128) /**< Minimum signed char value. */ 62 #define X_SCHAR_MAX 127 /**< Maximum signed char value. */ 63 #define X_UCHAR_MAX 255U /**< Maximum unsigned char value. */ 64 #define X_SHORT_MIN (-32768) /**< Minimum short value. */ 65 #define X_SHRT_MIN X_SHORT_MIN /**< This alias is compatible with limits.h. */ 66 #define X_SHORT_MAX 32767 /**< Maximum short value. */ 67 #define X_SHRT_MAX X_SHORT_MAX /**< This alias is compatible with limits.h. */ 68 #define X_USHORT_MAX 65535U /**< Maximum unsigned short value. */ 69 #define X_USHRT_MAX X_USHORT_MAX /**< This alias is compatible with limits.h. */ 70 #define X_INT_MIN (-2147483647-1) /**< Minimum int value. */ 71 #define X_INT_MAX 2147483647 /**< Maximum int value. */ 72 #define X_LONG_MIN X_INT_MIN /**< Minimum long value. */ 73 #define X_LONG_MAX X_INT_MAX /**< Maximum long value. */ 74 #define X_UINT_MAX 4294967295U /**< Maximum unsigned int value. */ 75 #define X_INT64_MIN (-9223372036854775807LL-1LL) /**< Minimum int64 value. */ 76 #define X_INT64_MAX 9223372036854775807LL /**< Maximum int64 value. */ 77 #define X_UINT64_MAX 18446744073709551615ULL /**< Maximum unsigned int64 value. */ 78 #ifdef _WIN32 /* Windows, of course, has to be a *little* different. */ 79 #define X_FLOAT_MAX 3.402823466e+38f 80 #else 81 #define X_FLOAT_MAX 3.40282347e+38f /**< Maximum float value. */ 82 #endif /* _WIN32 */ 83 #define X_FLOAT_MIN (-X_FLOAT_MAX) /**< Minimum float value. */ 84 #define X_DOUBLE_MAX 1.7976931348623157e+308 /**< Maximum double value. */ 85 #define X_DOUBLE_MIN (-X_DOUBLE_MAX) /**< Minimum double value. */ 86 87 /** This is the number of netCDF atomic types. */ 88 #define NUM_ATOMIC_TYPES (NC_MAX_ATOMIC_TYPE + 1) 89 90 /** Number of parameters needed for ZLIB filter. */ 91 #define CD_NELEMS_ZLIB 1 92 93 /** Get a pointer to the NC_FILE_INFO_T from dispatchdata field. */ 94 #define NC4_DATA(nc) ((NC_FILE_INFO_T *)(nc)->dispatchdata) 95 96 /** Set a pointer to the NC_FILE_INFO_T in the dispatchdata field. */ 97 #define NC4_DATA_SET(nc,data) ((nc)->dispatchdata = (void *)(data)) 98 99 /* Reserved attribute flags: must be powers of 2. */ 100 /** Hidden attributes; immutable and unreadable thru API. */ 101 #define HIDDENATTRFLAG 1 102 103 /** Readonly global attributes; readable, but immutable thru the 104 * API. */ 105 #define READONLYFLAG 2 106 107 /** Subset of readonly flags; readable by name only thru the API. */ 108 #define NAMEONLYFLAG 4 109 110 /** Subset of readonly flags; Value is actually in file. */ 111 #define MATERIALIZEDFLAG 8 112 113 /** Boolean type, to make the code easier to read. */ 114 typedef enum {NC_FALSE = 0, NC_TRUE = 1} nc_bool_t; 115 116 /* Forward declarations. */ 117 struct NC_GRP_INFO; 118 struct NC_TYPE_INFO; 119 120 /** 121 * This struct provides indexed Access to Meta-data objects. See the 122 * document docs/indexing.dox for detailed information. 123 * 124 * Basically it provides a common header and use NCindex instances 125 * instead of linked lists. 126 * 127 * WARNING: ALL OBJECTS THAT CAN BE INSERTED INTO AN NCindex MUST HAVE 128 * AN INSTANCE of NC_OBJ AS THE FIRST FIELD. 129 */ 130 typedef struct NC_OBJ 131 { 132 NC_SORT sort; /**< Type of object. */ 133 char* name; /**< Name, assumed to be null terminated. */ 134 size_t id; /**< This objects ID. */ 135 } NC_OBJ; 136 137 /** 138 * This struct holds information about reserved attributes. These 139 * attributes cannot be created or read by the user (through the 140 * netCDF API). */ 141 typedef struct NC_reservedatt 142 { 143 const char *name; /**< Name of the reserved attribute. */ 144 int flags; /**< Flags that control handling of reserved attribute. */ 145 } NC_reservedatt; 146 147 /** This is a struct to handle the dimension metadata. */ 148 typedef struct NC_DIM_INFO 149 { 150 NC_OBJ hdr; /**< The hdr contains the name and ID. */ 151 struct NC_GRP_INFO *container; /**< Pointer to containing group. */ 152 size_t len; /**< Length of this dimension. */ 153 nc_bool_t unlimited; /**< True if the dimension is unlimited */ 154 nc_bool_t extended; /**< True if the dimension needs to be extended. */ 155 nc_bool_t too_long; /**< True if len is too big to fit in local size_t. */ 156 void *format_dim_info; /**< Pointer to format-specific dim info. */ 157 struct NC_VAR_INFO *coord_var; /**< The coord var, if it exists. */ 158 } NC_DIM_INFO_T; 159 160 /** This is a struct to handle the attribute metadata. */ 161 typedef struct NC_ATT_INFO 162 { 163 NC_OBJ hdr; /**< The hdr contains the name and ID. */ 164 struct NC_OBJ *container; /**< Pointer to containing group|var. */ 165 int len; /**< Length of attribute data. */ 166 nc_bool_t dirty; /**< True if attribute modified. */ 167 nc_bool_t created; /**< True if attribute already created. */ 168 nc_type nc_typeid; /**< NetCDF type of attribute's data. */ 169 void *format_att_info; /**< Pointer to format-specific att info. */ 170 void *data; /**< The attribute data. */ 171 nc_vlen_t *vldata; /**< VLEN data (only used for vlen types). */ 172 char **stdata; /**< String data (only for string type). */ 173 } NC_ATT_INFO_T; 174 175 /** This is a struct to handle the var metadata. */ 176 typedef struct NC_VAR_INFO 177 { 178 NC_OBJ hdr; /**< The hdr contains the name and ID. */ 179 char *alt_name; /**< Used if name in dispatcher must be different from hdr.name. */ 180 struct NC_GRP_INFO *container; /**< Pointer to containing group. */ 181 size_t ndims; /**< Number of dims. */ 182 int *dimids; /**< Dim IDs. */ 183 NC_DIM_INFO_T **dim; /**< Pointer to array of NC_DIM_INFO_T. */ 184 nc_bool_t is_new_var; /**< True if variable is newly created. */ 185 nc_bool_t was_coord_var; /**< True if variable was a coordinate var, but either the dim or var has been renamed. */ 186 nc_bool_t became_coord_var; /**< True if variable _became_ a coordinate var, because either the dim or var has been renamed. */ 187 nc_bool_t fill_val_changed; /**< True if variable's fill value changes after it has been created. */ 188 nc_bool_t attr_dirty; /**< True if variable's attributes are dirty and should be rewritten. */ 189 nc_bool_t created; /**< Variable has already been created (_not_ that it was just created). */ 190 nc_bool_t written_to; /**< True if variable has data written to it. */ 191 struct NC_TYPE_INFO *type_info; /**< Contains info about the variable type. */ 192 int atts_read; /**< If true, the atts have been read. */ 193 nc_bool_t meta_read; /**< True if this vars metadata has been completely read. */ 194 nc_bool_t coords_read; /**< True if this var has hidden coordinates att, and it has been read. */ 195 NCindex *att; /**< List of NC_ATT_INFO_T. */ 196 nc_bool_t no_fill; /**< True if no fill value is defined for var. */ 197 void *fill_value; /**< Pointer to fill value, or NULL. */ 198 size_t *chunksizes; /**< For chunked storage, an array (size ndims) of chunksizes. */ 199 int storage; /**< Storage of this var, compact, contiguous, or chunked. */ 200 int endianness; /**< What endianness for the var? */ 201 int parallel_access; /**< Type of parallel access for I/O on variable (collective or independent). */ 202 nc_bool_t shuffle; /**< True if var has shuffle filter applied. */ 203 nc_bool_t fletcher32; /**< True if var has fletcher32 filter applied. */ 204 size_t chunk_cache_size; /**< Size in bytes of the var chunk chache. */ 205 size_t chunk_cache_nelems; /**< Number of slots in var chunk cache. */ 206 float chunk_cache_preemption; /**< Chunk cache preemtion policy. */ 207 void *format_var_info; /**< Pointer to any binary format info. */ 208 void* filters; /**< Record of the list of filters to be applied to var data; format dependent */ 209 } NC_VAR_INFO_T; 210 211 /** This is a struct to handle the field metadata from a user-defined 212 * type. */ 213 typedef struct NC_FIELD_INFO 214 { 215 NC_OBJ hdr; /**< The hdr contains the name and ID. */ 216 nc_type nc_typeid; /**< The type of this field. */ 217 size_t offset; /**< Offset in bytes of field. */ 218 int ndims; /**< Number of dims. */ 219 int *dim_size; /**< Dim sizes. */ 220 void *format_field_info; /**< Pointer to any binary format info for field. */ 221 } NC_FIELD_INFO_T; 222 223 /** This is a struct to handle metadata for a user-defined enum 224 * type. */ 225 typedef struct NC_ENUM_MEMBER_INFO 226 { 227 char *name; /**< Name of member. */ 228 void *value; /**< Value of member. */ 229 } NC_ENUM_MEMBER_INFO_T; 230 231 /** This is a struct to handle metadata for a user-defined type. */ 232 typedef struct NC_TYPE_INFO 233 { 234 NC_OBJ hdr; /**< The hdr contains the name and ID. */ 235 struct NC_GRP_INFO *container; /**< Containing group */ 236 unsigned rc; /**< Ref. count of objects using this type */ 237 int endianness; /**< What endianness for the type? */ 238 size_t size; /**< Size of the type in memory, in bytes */ 239 nc_bool_t committed; /**< True when datatype is committed in the file */ 240 nc_type nc_type_class; /**< NC_VLEN, NC_COMPOUND, NC_OPAQUE, NC_ENUM, NC_INT, NC_FLOAT, or NC_STRING. */ 241 void *format_type_info; /**< HDF5-specific type info. */ 242 243 /** Information for each type or class */ 244 union { 245 struct { 246 NClist* enum_member; /**< <! NClist<NC_ENUM_MEMBER_INFO_T*> */ 247 nc_type base_nc_typeid; /**< Typeid of the base type. */ 248 } e; /**< Enum */ 249 struct Fields { 250 NClist* field; /**< <! NClist<NC_FIELD_INFO_T*> */ 251 } c; /**< Compound */ 252 struct { 253 nc_type base_nc_typeid; /**< Typeid of the base type. */ 254 } v; /**< Variable-length. */ 255 } u; /**< Union of structs, for each type/class. */ 256 } NC_TYPE_INFO_T; 257 258 /** This holds information for one group. Groups reproduce with 259 * parthenogenesis. */ 260 typedef struct NC_GRP_INFO 261 { 262 NC_OBJ hdr; /**< The hdr contains the name and ID. */ 263 void *format_grp_info; /**< Pointer to binary format info for group. */ 264 struct NC_FILE_INFO *nc4_info; /**< Pointer containing NC_FILE_INFO_T. */ 265 struct NC_GRP_INFO *parent; /**< Pointer tp parent group. */ 266 int atts_read; /**< True if atts have been read for this group. */ 267 NCindex* children; /**< NCindex<struct NC_GRP_INFO*> */ 268 NCindex* dim; /**< NCindex<NC_DIM_INFO_T> * */ 269 NCindex* att; /**< NCindex<NC_ATT_INFO_T> * */ 270 NCindex* type; /**< NCindex<NC_TYPE_INFO_T> * */ 271 /* Note that this is the list of vars with position == varid */ 272 NCindex* vars; /**< NCindex<NC_VAR_INFO_T> * */ 273 } NC_GRP_INFO_T; 274 275 /* These constants apply to the cmode parameter in the 276 * HDF5_FILE_INFO_T defined below. */ 277 /* Make sure they do not conflict with defined flags in netcdf.h */ 278 #define NC_CREAT 0x10002 /**< in create phase, cleared by ncendef */ 279 #define NC_INDEF 0x10008 /**< in define mode, cleared by ncendef */ 280 #define NC_NSYNC 0x10010 /**< synchronise numrecs on change */ 281 #define NC_HSYNC 0x10020 /**< synchronise whole header on change */ 282 #define NC_NDIRTY 0x10040 /**< numrecs has changed */ 283 #define NC_HDIRTY 0x10080 /**< header info has changed */ 284 285 /** This is the metadata we need to keep track of for each 286 * netcdf-4/HDF5 file. */ 287 288 typedef struct NC_FILE_INFO 289 { 290 NC_OBJ hdr; 291 NC *controller; /**< Pointer to containing NC. */ 292 #ifdef USE_PARALLEL4 293 MPI_Comm comm; /**< Copy of MPI Communicator used to open the file. */ 294 MPI_Info info; /**< Copy of MPI Information Object used to open the file. */ 295 #endif 296 int flags; /**< Flags used to open the file. */ 297 int cmode; /**< Create mode used to create the file. */ 298 nc_bool_t parallel; /**< True if file is open for parallel access */ 299 nc_bool_t redef; /**< True if redefining an existing file */ 300 int fill_mode; /**< Fill mode for vars - Unused internally currently */ 301 nc_bool_t no_write; /**< true if nc_open has mode NC_NOWRITE. */ 302 NC_GRP_INFO_T *root_grp; /**< Pointer to root group. */ 303 short next_nc_grpid; /**< Next available group ID. */ 304 int next_typeid; /**< Next available type ID. */ 305 int next_dimid; /**< Next available dim ID. */ 306 /* Provide convenience vectors indexed by the object id. This 307 allows for direct conversion of e.g. an nc_type to the 308 corresponding NC_TYPE_INFO_T object. */ 309 NClist *alldims; /**< List of all dims. */ 310 NClist *alltypes; /**< List of all types. */ 311 NClist *allgroups; /**< List of all groups, including root group. */ 312 void *format_file_info; /**< Pointer to binary format info for file. */ 313 NC4_Provenance provenance; /**< File provenence info. */ 314 struct NC4_Memio 315 { 316 NC_memio memio; /**< What we sent to image_init and what comes back. */ 317 int locked; /**< Do not copy and do not free. */ 318 int persist; /**< Should file be persisted out on close? */ 319 int inmemory; /**< NC_INMEMORY flag was set. */ 320 int diskless; /**< NC_DISKLESS flag was set => inmemory. */ 321 int created; /**< 1 => create, 0 => open. */ 322 unsigned int imageflags; /**< for H5LTopen_file_image. */ 323 size_t initialsize; /**< Initial size. */ 324 void *udata; /**< Extra memory allocated in NC4_image_init. */ 325 } mem; 326 } NC_FILE_INFO_T; 327 328 /** Variable Length Datatype struct in memory. Must be identical to 329 * HDF5 hvl_t. (This is only used for VL sequences, not VL strings, 330 * which are stored in char *'s) */ 331 typedef struct 332 { 333 size_t len; /**< Length of VL data (in base type units) */ 334 void *p; /**< Pointer to VL data */ 335 } nc_hvl_t; 336 337 /* Misc functions */ 338 extern int NC4_inq_atomic_type(nc_type typeid1, char *name, size_t *size); 339 extern int NC4_lookup_atomic_type(const char *name, nc_type* idp, size_t *sizep); 340 341 /* These functions convert between netcdf and HDF5 types. */ 342 extern int nc4_get_typelen_mem(NC_FILE_INFO_T *h5, nc_type xtype, size_t *len); 343 extern int nc4_convert_type(const void *src, void *dest, const nc_type src_type, 344 const nc_type dest_type, const size_t len, int *range_error, 345 const void *fill_value, int strict_nc3); 346 347 /* These functions do HDF5 things. */ 348 extern int nc4_reopen_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var); 349 extern int nc4_read_atts(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var); 350 351 /* Find items in the in-memory lists of metadata. */ 352 extern int nc4_find_nc_grp_h5(int ncid, NC **nc, NC_GRP_INFO_T **grp, 353 NC_FILE_INFO_T **h5); 354 extern int nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5); 355 extern int nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp); 356 extern int nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim, 357 NC_GRP_INFO_T **dim_grp); 358 extern int nc4_find_var(NC_GRP_INFO_T *grp, const char *name, NC_VAR_INFO_T **var); 359 extern int nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len); 360 extern int nc4_find_type(const NC_FILE_INFO_T *h5, int typeid1, NC_TYPE_INFO_T **type); 361 extern NC_TYPE_INFO_T *nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name); 362 extern NC_TYPE_INFO_T *nc4_rec_find_equal_type(NC_GRP_INFO_T *start_grp, int ncid1, 363 NC_TYPE_INFO_T *type); 364 extern int nc4_find_nc_att(int ncid, int varid, const char *name, int attnum, 365 NC_ATT_INFO_T **att); 366 extern int nc4_find_grp_h5_var(int ncid, int varid, NC_FILE_INFO_T **h5, 367 NC_GRP_INFO_T **grp, NC_VAR_INFO_T **var); 368 extern int nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, 369 int attnum, NC_ATT_INFO_T **att); 370 extern int nc4_get_typeclass(const NC_FILE_INFO_T *h5, nc_type xtype, 371 int *type_class); 372 373 /* Free various types */ 374 extern int nc4_type_free(NC_TYPE_INFO_T *type); 375 376 /* These list functions add and delete vars, atts. */ 377 extern int nc4_nc4f_list_add(NC *nc, const char *path, int mode); 378 extern int nc4_nc4f_list_del(NC_FILE_INFO_T *h5); 379 extern int nc4_file_list_add(int ncid, const char *path, int mode, 380 void **dispatchdata); 381 extern int nc4_file_list_get(int ncid, char **path, int *mode, 382 void **dispatchdata); 383 extern int nc4_file_list_del(int ncid); 384 extern int nc4_file_change_ncid(int ncid, unsigned short new_ncid_index); 385 extern int nc4_var_list_add(NC_GRP_INFO_T* grp, const char* name, int ndims, 386 NC_VAR_INFO_T **var); 387 extern int nc4_var_list_add2(NC_GRP_INFO_T* grp, const char* name, 388 NC_VAR_INFO_T **var); 389 extern int nc4_var_set_ndims(NC_VAR_INFO_T *var, int ndims); 390 extern int nc4_var_list_del(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var); 391 extern int nc4_dim_list_add(NC_GRP_INFO_T *grp, const char *name, size_t len, 392 int assignedid, NC_DIM_INFO_T **dim); 393 extern int nc4_dim_list_del(NC_GRP_INFO_T *grp, NC_DIM_INFO_T *dim); 394 extern int nc4_type_new(size_t size, const char *name, int assignedid, 395 NC_TYPE_INFO_T **type); 396 extern int nc4_type_list_add(NC_GRP_INFO_T *grp, size_t size, const char *name, 397 NC_TYPE_INFO_T **type); 398 extern int nc4_type_list_del(NC_GRP_INFO_T *grp, NC_TYPE_INFO_T *type); 399 extern int nc4_type_free(NC_TYPE_INFO_T *type); 400 extern int nc4_field_list_add(NC_TYPE_INFO_T* parent, const char *name, 401 size_t offset, nc_type xtype, int ndims, 402 const int *dim_sizesp); 403 extern int nc4_att_list_add(NCindex *list, const char *name, NC_ATT_INFO_T **att); 404 extern int nc4_att_list_del(NCindex *list, NC_ATT_INFO_T *att); 405 extern int nc4_grp_list_add(NC_FILE_INFO_T *h5, NC_GRP_INFO_T *parent, char *name, 406 NC_GRP_INFO_T **grp); 407 extern int nc4_build_root_grp(NC_FILE_INFO_T *h5); 408 extern int nc4_rec_grp_del(NC_GRP_INFO_T *grp); 409 extern int nc4_enum_member_add(NC_TYPE_INFO_T *type, size_t size, const char *name, 410 const void *value); 411 extern int nc4_att_free(NC_ATT_INFO_T *att); 412 413 /* Check and normalize names. */ 414 extern int NC_check_name(const char *name); 415 extern int nc4_check_name(const char *name, char *norm_name); 416 extern int nc4_normalize_name(const char *name, char *norm_name); 417 extern int nc4_check_dup_name(NC_GRP_INFO_T *grp, char *norm_name); 418 419 /* Get the fill value for a var. */ 420 extern int nc4_get_fill_value(NC_FILE_INFO_T *h5, NC_VAR_INFO_T *var, void **fillp); 421 422 /* Find default fill value. */ 423 extern int nc4_get_default_fill_value(nc_type typecode, void *fill_value); 424 425 /* Get an att given pointers to file, group, and perhaps ver info. */ 426 extern int nc4_get_att_ptrs(NC_FILE_INFO_T *h5, NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, 427 const char *name, nc_type *xtype, nc_type mem_type, 428 size_t *lenp, int *attnum, void *data); 429 430 /* Close the file. */ 431 extern int nc4_close_netcdf4_file(NC_FILE_INFO_T *h5, int abort, NC_memio *memio); 432 433 /* Compute default chunksizes */ 434 extern int nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var); 435 extern int nc4_check_chunksizes(NC_GRP_INFO_T* grp, NC_VAR_INFO_T* var, const size_t* chunksizes); 436 437 /* HDF5 initialization/finalization */ 438 extern int nc4_hdf5_initialized; 439 extern void nc4_hdf5_initialize(void); 440 extern void nc4_hdf5_finalize(void); 441 442 /* This is only included if --enable-logging is used for configure; it 443 prints info about the metadata to stderr. */ 444 #ifdef LOGGING 445 extern int log_metadata_nc(NC_FILE_INFO_T *h5); 446 #endif 447 448 /** @internal Names of atomic types. */ 449 extern const char* nc4_atomic_name[NUM_ATOMIC_TYPES]; 450 451 /* Binary searcher for reserved attributes */ 452 extern const NC_reservedatt* NC_findreserved(const char* name); 453 454 /* Generic reserved Attributes */ 455 #define NC_ATT_REFERENCE_LIST "REFERENCE_LIST" 456 #define NC_ATT_CLASS "CLASS" 457 #define NC_ATT_DIMENSION_LIST "DIMENSION_LIST" 458 #define NC_ATT_NAME "NAME" 459 #define NC_ATT_COORDINATES "_Netcdf4Coordinates" /*see hdf5internal.h:COORDINATES*/ 460 #define NC_ATT_FORMAT "_Format" 461 #define NC_ATT_DIMID_NAME "_Netcdf4Dimid" 462 #define NC_ATT_NC3_STRICT_NAME "_nc3_strict" 463 #define NC_XARRAY_DIMS "_ARRAY_DIMENSIONS" 464 #define NC_NCZARR_ATTR "_NCZARR_ATTR" 465 466 #endif /* _NC4INTERNAL_ */ 467