Merge branch 'master' into housekeeping

This commit is contained in:
Ward Fisher 2018-09-14 15:55:29 -06:00
commit e3cc0185cc
17 changed files with 264 additions and 468 deletions

View File

@ -59,6 +59,7 @@ typedef struct NC_HDF5_FILE_INFO
/* These functions do HDF5 things. */ /* These functions do HDF5 things. */
int rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid); int rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid);
int rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid); int rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid);
void reportopenobjects(int log, hid_t);
/* Used by NC4_set_provenance */ /* Used by NC4_set_provenance */

View File

@ -340,31 +340,27 @@ int nc4_reopen_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var);
int nc4_adjust_var_cache(NC_GRP_INFO_T *grp, NC_VAR_INFO_T * var); int nc4_adjust_var_cache(NC_GRP_INFO_T *grp, NC_VAR_INFO_T * var);
int nc4_read_atts(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var); int nc4_read_atts(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var);
/* The following functions manipulate the in-memory linked list of /* Find items in the in-memory lists of metadata. */
metadata, without using HDF calls. */
int nc4_find_nc_grp_h5(int ncid, NC **nc, NC_GRP_INFO_T **grp, int nc4_find_nc_grp_h5(int ncid, NC **nc, NC_GRP_INFO_T **grp,
NC_FILE_INFO_T **h5); NC_FILE_INFO_T **h5);
int nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5); int nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5);
int nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp); int nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp);
NC_GRP_INFO_T *nc4_find_nc_grp(int ncid); int nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim,
NC_GRP_INFO_T *nc4_rec_find_grp(NC_FILE_INFO_T *h5, int target_nc_grpid); NC_GRP_INFO_T **dim_grp);
NC *nc4_find_nc_file(int ncid, NC_FILE_INFO_T**);
int nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim, NC_GRP_INFO_T **dim_grp);
int nc4_find_var(NC_GRP_INFO_T *grp, const char *name, NC_VAR_INFO_T **var); int nc4_find_var(NC_GRP_INFO_T *grp, const char *name, NC_VAR_INFO_T **var);
int nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len); int nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len);
int nc4_find_type(const NC_FILE_INFO_T *h5, int typeid1, NC_TYPE_INFO_T **type); int nc4_find_type(const NC_FILE_INFO_T *h5, int typeid1, NC_TYPE_INFO_T **type);
NC_TYPE_INFO_T *nc4_rec_find_nc_type(NC_FILE_INFO_T *h5, nc_type target_nc_typeid); NC_TYPE_INFO_T *nc4_rec_find_hdf_type(NC_FILE_INFO_T* h5,
NC_TYPE_INFO_T *nc4_rec_find_hdf_type(NC_FILE_INFO_T* h5, hid_t target_hdf_typeid); hid_t target_hdf_typeid);
NC_TYPE_INFO_T *nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name); NC_TYPE_INFO_T *nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name);
NC_TYPE_INFO_T *nc4_rec_find_equal_type(NC_GRP_INFO_T *start_grp, int ncid1, NC_TYPE_INFO_T *type); NC_TYPE_INFO_T *nc4_rec_find_equal_type(NC_GRP_INFO_T *start_grp, int ncid1,
NC_TYPE_INFO_T *type);
int nc4_find_nc_att(int ncid, int varid, const char *name, int attnum, int nc4_find_nc_att(int ncid, int varid, const char *name, int attnum,
NC_ATT_INFO_T **att); NC_ATT_INFO_T **att);
int nc4_find_g_var_nc(NC *nc, int ncid, int varid, int nc4_find_grp_h5_var(int ncid, int varid, NC_FILE_INFO_T **h5,
NC_GRP_INFO_T **grp, NC_VAR_INFO_T **var); NC_GRP_INFO_T **grp, NC_VAR_INFO_T **var);
int nc4_find_grp_h5_var(int ncid, int varid, NC_FILE_INFO_T **h5, NC_GRP_INFO_T **grp, int nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name,
NC_VAR_INFO_T **var); int attnum, NC_ATT_INFO_T **att);
int nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum,
NC_ATT_INFO_T **att);
int nc4_get_hdf_typeid(NC_FILE_INFO_T *h5, nc_type xtype, int nc4_get_hdf_typeid(NC_FILE_INFO_T *h5, nc_type xtype,
hid_t *hdf_typeid, int endianness); hid_t *hdf_typeid, int endianness);
int nc4_get_typeclass(const NC_FILE_INFO_T *h5, nc_type xtype, int nc4_get_typeclass(const NC_FILE_INFO_T *h5, nc_type xtype,
@ -423,7 +419,7 @@ extern void nc4_hdf5_initialize(void);
/* This is only included if --enable-logging is used for configure; it /* This is only included if --enable-logging is used for configure; it
prints info about the metadata to stderr. */ prints info about the metadata to stderr. */
#ifdef LOGGING #ifdef LOGGING
int log_metadata_nc(NC *nc); int log_metadata_nc(NC_FILE_INFO_T *h5);
#endif #endif
/* Define accessors for the dispatchdata */ /* Define accessors for the dispatchdata */

View File

@ -659,7 +659,7 @@ NC_HDF4_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
#ifdef LOGGING #ifdef LOGGING
/* This will print out the names, types, lens, etc of the vars and /* This will print out the names, types, lens, etc of the vars and
atts in the file, if the logging level is 2 or greater. */ atts in the file, if the logging level is 2 or greater. */
log_metadata_nc(h5->root_grp->nc4_info->controller); log_metadata_nc(h5);
#endif #endif
return retval; return retval;

View File

@ -50,15 +50,15 @@ int
NC_HDF4_inq_format_extended(int ncid, int *formatp, int *modep) NC_HDF4_inq_format_extended(int ncid, int *formatp, int *modep)
{ {
NC *nc; NC *nc;
NC_FILE_INFO_T* h5; int retval;
LOG((2, "%s: ncid 0x%x", __func__, ncid)); LOG((2, "%s: ncid 0x%x", __func__, ncid));
if (!(nc = nc4_find_nc_file(ncid, &h5))) if ((retval = nc4_find_nc_grp_h5(ncid, &nc, NULL, NULL)))
return NC_EBADID; return NC_EBADID;
if (modep) if (modep)
*modep = (nc->mode|NC_NETCDF4); *modep = nc->mode|NC_NETCDF4;
if (formatp) if (formatp)
*formatp = NC_FORMATX_NC_HDF4; *formatp = NC_FORMATX_NC_HDF4;

View File

@ -33,9 +33,6 @@ int
NC_HDF4_get_vara(int ncid, int varid, const size_t *startp, NC_HDF4_get_vara(int ncid, int varid, const size_t *startp,
const size_t *countp, void *ip, int memtype) const size_t *countp, void *ip, int memtype)
{ {
NC *nc;
NC_FILE_INFO_T* h5;
NC_GRP_INFO_T *grp;
NC_VAR_HDF4_INFO_T *hdf4_var; NC_VAR_HDF4_INFO_T *hdf4_var;
NC_VAR_INFO_T *var; NC_VAR_INFO_T *var;
int32 start32[NC_MAX_VAR_DIMS], edge32[NC_MAX_VAR_DIMS]; int32 start32[NC_MAX_VAR_DIMS], edge32[NC_MAX_VAR_DIMS];
@ -52,22 +49,14 @@ NC_HDF4_get_vara(int ncid, int varid, const size_t *startp,
if (!startp || !countp || !ip) if (!startp || !countp || !ip)
return NC_EINVAL; return NC_EINVAL;
/* Find file info. */
if (!(nc = nc4_find_nc_file(ncid, &h5)))
return NC_EBADID;
/* Find our metadata for this file, group, and var. */ /* Find our metadata for this file, group, and var. */
if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var))) if ((retval = nc4_find_grp_h5_var(ncid, varid, NULL, NULL, &var)))
return retval; return retval;
assert(var && var->hdr.name && var->format_var_info);
assert(grp && var && var->hdr.name && var->format_var_info);
/* Get the HDF4 specific var metadata. */ /* Get the HDF4 specific var metadata. */
hdf4_var = (NC_VAR_HDF4_INFO_T *)var->format_var_info; hdf4_var = (NC_VAR_HDF4_INFO_T *)var->format_var_info;
h5 = NC4_DATA(nc);
assert(h5);
/* Convert starts/edges to the int32 type HDF4 wants. Also learn /* Convert starts/edges to the int32 type HDF4 wants. Also learn
* how many elements of data are being read. */ * how many elements of data are being read. */
for (d = 0; d < var->ndims; d++) for (d = 0; d < var->ndims; d++)

View File

@ -41,16 +41,21 @@ static const NC_reservedatt NC_reserved[NRESERVED] = {
{NC3_STRICT_ATT_NAME, READONLYFLAG|MATERIALIZEDFLAG}, /*_nc3_strict*/ {NC3_STRICT_ATT_NAME, READONLYFLAG|MATERIALIZEDFLAG}, /*_nc3_strict*/
}; };
extern void reportopenobjects(int log, hid_t);
/* Forward */ /* Forward */
static int NC4_enddef(int ncid); static int NC4_enddef(int ncid);
static void dumpopenobjects(NC_FILE_INFO_T* h5); static void dumpopenobjects(NC_FILE_INFO_T* h5);
/* These hold the file caching settings for the library. */
size_t nc4_chunk_cache_size = CHUNK_CACHE_SIZE; /**< Default chunk cache size. */
size_t nc4_chunk_cache_nelems = CHUNK_CACHE_NELEMS; /**< Default chunk cache number of elements. */
float nc4_chunk_cache_preemption = CHUNK_CACHE_PREEMPTION; /**< Default chunk cache preemption. */
/** /**
* @internal Define a binary searcher for reserved attributes * @internal Define a binary searcher for reserved attributes
* @param name for which to search * @param name for which to search
* @return pointer to the matchig NC_reservedatt structure. * @return pointer to the matchig NC_reservedatt structure.
* @return NULL if not found.
* @author Dennis Heimbigner
*/ */
const NC_reservedatt* const NC_reservedatt*
NC_findreserved(const char* name) NC_findreserved(const char* name)
@ -109,7 +114,7 @@ sync_netcdf4_file(NC_FILE_INFO_T *h5)
#ifdef LOGGING #ifdef LOGGING
/* This will print out the names, types, lens, etc of the vars and /* This will print out the names, types, lens, etc of the vars and
atts in the file, if the logging level is 2 or greater. */ atts in the file, if the logging level is 2 or greater. */
log_metadata_nc(h5->root_grp->nc4_info->controller); log_metadata_nc(h5);
#endif #endif
/* Write any metadata that has changed. */ /* Write any metadata that has changed. */
@ -155,16 +160,20 @@ sync_netcdf4_file(NC_FILE_INFO_T *h5)
* @param memio the place to return a core image if not NULL * @param memio the place to return a core image if not NULL
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @author Ed Hartnett * @return ::NC_EHDFERR HDF5 could not close the file.
* @return ::NC_EINDEFINE Classic model file is in define mode.
* @author Ed Hartnett, Dennis Heimbigner
*/ */
int int
nc4_close_netcdf4_file(NC_FILE_INFO_T *h5, int abort, NC_memio* memio) nc4_close_netcdf4_file(NC_FILE_INFO_T *h5, int abort, NC_memio* memio)
{ {
NC_HDF5_FILE_INFO_T *hdf5_info; NC_HDF5_FILE_INFO_T *hdf5_info;
int retval = NC_NOERR; int retval;
assert(h5 && h5->root_grp && h5->format_file_info); assert(h5 && h5->root_grp && h5->format_file_info);
LOG((3, "%s: h5->path %s abort %d", __func__, h5->controller->path, abort)); LOG((3, "%s: h5->path %s abort %d", __func__, h5->controller->path, abort));
/* Get HDF5 specific info. */
hdf5_info = (NC_HDF5_FILE_INFO_T *)h5->format_file_info; hdf5_info = (NC_HDF5_FILE_INFO_T *)h5->format_file_info;
/* According to the docs, always end define mode on close. */ /* According to the docs, always end define mode on close. */
@ -175,12 +184,12 @@ nc4_close_netcdf4_file(NC_FILE_INFO_T *h5, int abort, NC_memio* memio)
* file. */ * file. */
if (!h5->no_write && !abort) if (!h5->no_write && !abort)
if ((retval = sync_netcdf4_file(h5))) if ((retval = sync_netcdf4_file(h5)))
goto exit; return retval;
/* Delete all the list contents for vars, dims, and atts, in each /* Delete all the list contents for vars, dims, and atts, in each
* group. */ * group. */
if ((retval = nc4_rec_grp_del(h5->root_grp))) if ((retval = nc4_rec_grp_del(h5->root_grp)))
goto exit; return retval;
/* Free lists of dims, groups, and types in the root group. */ /* Free lists of dims, groups, and types in the root group. */
nclistfree(h5->alldims); nclistfree(h5->alldims);
@ -209,7 +218,7 @@ nc4_close_netcdf4_file(NC_FILE_INFO_T *h5, int abort, NC_memio* memio)
if (hdf5_info->hdfid > 0 && H5Fclose(hdf5_info->hdfid) < 0) if (hdf5_info->hdfid > 0 && H5Fclose(hdf5_info->hdfid) < 0)
{ {
dumpopenobjects(h5); dumpopenobjects(h5);
BAIL(NC_EHDFERR); return NC_EHDFERR;
} }
/* If inmemory is used and user wants the final memory block, /* If inmemory is used and user wants the final memory block,
@ -235,16 +244,21 @@ nc4_close_netcdf4_file(NC_FILE_INFO_T *h5, int abort, NC_memio* memio)
if (h5->format_file_info) if (h5->format_file_info)
free(h5->format_file_info); free(h5->format_file_info);
exit:
/* Free the nc4_info struct; above code should have reclaimed /* Free the nc4_info struct; above code should have reclaimed
everything else */ everything else */
if (!retval)
free(h5); free(h5);
return retval;
return NC_NOERR;
} }
/**
* @internal Output a list of still-open objects in the HDF5
* file. This is only called if the file fails to close cleanly.
*
* @param h5 Pointer to file info.
*
* @author Dennis Heimbigner
*/
static void static void
dumpopenobjects(NC_FILE_INFO_T* h5) dumpopenobjects(NC_FILE_INFO_T* h5)
{ {
@ -286,10 +300,6 @@ dumpopenobjects(NC_FILE_INFO_T* h5)
return; return;
} }
size_t nc4_chunk_cache_size = CHUNK_CACHE_SIZE; /**< Default chunk cache size. */
size_t nc4_chunk_cache_nelems = CHUNK_CACHE_NELEMS; /**< Default chunk cache number of elements. */
float nc4_chunk_cache_preemption = CHUNK_CACHE_PREEMPTION; /**< Default chunk cache preemption. */
/** /**
* Set chunk cache size. Only affects files opened/created *after* it * Set chunk cache size. Only affects files opened/created *after* it
* is called. * is called.
@ -401,13 +411,14 @@ nc_get_chunk_cache_ints(int *sizep, int *nelemsp, int *preemptionp)
int int
NC4_set_fill(int ncid, int fillmode, int *old_modep) NC4_set_fill(int ncid, int fillmode, int *old_modep)
{ {
NC *nc;
NC_FILE_INFO_T *nc4_info; NC_FILE_INFO_T *nc4_info;
int retval;
LOG((2, "%s: ncid 0x%x fillmode %d", __func__, ncid, fillmode)); LOG((2, "%s: ncid 0x%x fillmode %d", __func__, ncid, fillmode));
if (!(nc = nc4_find_nc_file(ncid,&nc4_info))) /* Get pointer to file info. */
return NC_EBADID; if ((retval = nc4_find_grp_h5(ncid, NULL, &nc4_info)))
return retval;
assert(nc4_info); assert(nc4_info);
/* Trying to set fill on a read-only file? You sicken me! */ /* Trying to set fill on a read-only file? You sicken me! */
@ -424,7 +435,6 @@ NC4_set_fill(int ncid, int fillmode, int *old_modep)
nc4_info->fill_mode = fillmode; nc4_info->fill_mode = fillmode;
return NC_NOERR; return NC_NOERR;
} }
@ -441,12 +451,13 @@ int
NC4_redef(int ncid) NC4_redef(int ncid)
{ {
NC_FILE_INFO_T *nc4_info; NC_FILE_INFO_T *nc4_info;
int retval;
LOG((1, "%s: ncid 0x%x", __func__, ncid)); LOG((1, "%s: ncid 0x%x", __func__, ncid));
/* Find this file's metadata. */ /* Find this file's metadata. */
if (!(nc4_find_nc_file(ncid,&nc4_info))) if ((retval = nc4_find_grp_h5(ncid, NULL, &nc4_info)))
return NC_EBADID; return retval;
assert(nc4_info); assert(nc4_info);
/* If we're already in define mode, return an error. */ /* If we're already in define mode, return an error. */
@ -484,9 +495,6 @@ int
NC4__enddef(int ncid, size_t h_minfree, size_t v_align, NC4__enddef(int ncid, size_t h_minfree, size_t v_align,
size_t v_minfree, size_t r_align) size_t v_minfree, size_t r_align)
{ {
if (nc4_find_nc_file(ncid,NULL) == NULL)
return NC_EBADID;
return NC4_enddef(ncid); return NC4_enddef(ncid);
} }
@ -501,29 +509,26 @@ NC4__enddef(int ncid, size_t h_minfree, size_t v_align,
* @return ::NC_EBADGRPID Bad group ID. * @return ::NC_EBADGRPID Bad group ID.
* @author Ed Hartnett * @author Ed Hartnett
*/ */
static int NC4_enddef(int ncid) static int
NC4_enddef(int ncid)
{ {
NC *nc;
NC_FILE_INFO_T *nc4_info; NC_FILE_INFO_T *nc4_info;
NC_GRP_INFO_T *grp; NC_GRP_INFO_T *grp;
NC_VAR_INFO_T *var;
int i; int i;
int retval;
LOG((1, "%s: ncid 0x%x", __func__, ncid)); LOG((1, "%s: ncid 0x%x", __func__, ncid));
if (!(nc = nc4_find_nc_file(ncid, &nc4_info))) /* Find pointer to group and nc4_info. */
return NC_EBADID; if ((retval = nc4_find_nc_grp_h5(ncid, NULL, &grp, &nc4_info)))
assert(nc4_info); return retval;
/* Find info for this file and group */
if (!(grp = nc4_rec_find_grp(nc4_info, (ncid & GRP_ID_MASK))))
return NC_EBADGRPID;
/* When exiting define mode, mark all variable written. */ /* When exiting define mode, mark all variable written. */
for (i = 0; i < ncindexsize(grp->vars); i++) for (i = 0; i < ncindexsize(grp->vars); i++)
{ {
NC_VAR_INFO_T *var; var = (NC_VAR_INFO_T *)ncindexith(grp->vars, i);
if (!(var = (NC_VAR_INFO_T *)ncindexith(grp->vars, i))) assert(var);
continue;
var->written_to = NC_TRUE; var->written_to = NC_TRUE;
} }
@ -537,23 +542,24 @@ static int NC4_enddef(int ncid)
* @param ncid File and group ID. * @param ncid File and group ID.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @return ::NC_EBADID Bad ncid.
* @return ::NC_EINDEFINE Classic model file is in define mode.
* @author Ed Hartnett * @author Ed Hartnett
*/ */
int int
NC4_sync(int ncid) NC4_sync(int ncid)
{ {
NC *nc;
int retval;
NC_FILE_INFO_T *nc4_info; NC_FILE_INFO_T *nc4_info;
int retval;
LOG((2, "%s: ncid 0x%x", __func__, ncid)); LOG((2, "%s: ncid 0x%x", __func__, ncid));
if (!(nc = nc4_find_nc_file(ncid,&nc4_info))) if ((retval = nc4_find_grp_h5(ncid, NULL, &nc4_info)))
return NC_EBADID; return retval;
assert(nc4_info); assert(nc4_info);
/* If we're in define mode, we can't sync. */ /* If we're in define mode, we can't sync. */
if (nc4_info && nc4_info->flags & NC_INDEF) if (nc4_info->flags & NC_INDEF)
{ {
if (nc4_info->cmode & NC_CLASSIC_MODEL) if (nc4_info->cmode & NC_CLASSIC_MODEL)
return NC_EINDEFINE; return NC_EINDEFINE;
@ -581,17 +587,16 @@ int
NC4_abort(int ncid) NC4_abort(int ncid)
{ {
NC *nc; NC *nc;
NC_FILE_INFO_T *nc4_info;
int delete_file = 0; int delete_file = 0;
char path[NC_MAX_NAME + 1]; char path[NC_MAX_NAME + 1];
int retval = NC_NOERR; int retval;
NC_FILE_INFO_T* nc4_info;
LOG((2, "%s: ncid 0x%x", __func__, ncid)); LOG((2, "%s: ncid 0x%x", __func__, ncid));
/* Find metadata for this file. */ /* Find metadata for this file. */
if (!(nc = nc4_find_nc_file(ncid,&nc4_info))) if ((retval = nc4_find_nc_grp_h5(ncid, &nc, NULL, &nc4_info)))
return NC_EBADID; return retval;
assert(nc4_info); assert(nc4_info);
/* If we're in define mode, but not redefing the file, delete it. */ /* If we're in define mode, but not redefing the file, delete it. */
@ -611,7 +616,7 @@ NC4_abort(int ncid)
if (remove(path) < 0) if (remove(path) < 0)
return NC_ECANTREMOVE; return NC_ECANTREMOVE;
return retval; return NC_NOERR;
} }
/** /**

View File

@ -539,7 +539,7 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc)
#ifdef LOGGING #ifdef LOGGING
/* This will print out the names, types, lens, etc of the vars and /* This will print out the names, types, lens, etc of the vars and
atts in the file, if the logging level is 2 or greater. */ atts in the file, if the logging level is 2 or greater. */
log_metadata_nc(nc); log_metadata_nc(nc4_info);
#endif #endif
/* Close the property list. */ /* Close the property list. */

View File

@ -72,13 +72,11 @@ NC4_inq_type_equal(int ncid1, nc_type typeid1, int ncid2,
/* Not atomic types - so find type1 and type2 information. */ /* Not atomic types - so find type1 and type2 information. */
if ((retval = nc4_find_nc4_grp(ncid1, &grpone))) if ((retval = nc4_find_nc4_grp(ncid1, &grpone)))
return retval; return retval;
if (!(type1 = nc4_rec_find_nc_type(grpone->nc4_info, if (!(type1 = nclistget(grpone->nc4_info->alltypes, typeid1)))
typeid1)))
return NC_EBADTYPE; return NC_EBADTYPE;
if ((retval = nc4_find_nc4_grp(ncid2, &grptwo))) if ((retval = nc4_find_nc4_grp(ncid2, &grptwo)))
return retval; return retval;
if (!(type2 = nc4_rec_find_nc_type(grptwo->nc4_info, if (!(type2 = nclistget(grptwo->nc4_info->alltypes, typeid2)))
typeid2)))
return NC_EBADTYPE; return NC_EBADTYPE;
/* Are the two types equal? */ /* Are the two types equal? */

View File

@ -817,21 +817,14 @@ NC4_def_var_chunking(int ncid, int varid, int contiguous, const size_t *chunksiz
int int
nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp) nc_def_var_chunking_ints(int ncid, int varid, int contiguous, int *chunksizesp)
{ {
NC *nc;
NC_GRP_INFO_T *grp;
NC_VAR_INFO_T *var; NC_VAR_INFO_T *var;
NC_FILE_INFO_T *h5;
size_t *cs = NULL; size_t *cs = NULL;
int i, retval; int i, retval;
/* Find this ncid's file info. */ /* Get pointer to the var. */
if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) if ((retval = nc4_find_grp_h5_var(ncid, varid, NULL, NULL, &var)))
return retval;
assert(nc);
/* Find var cause I need the number of dims. */
if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var)))
return retval; return retval;
assert(var);
/* Allocate space for the size_t copy of the chunksizes array. */ /* Allocate space for the size_t copy of the chunksizes array. */
if (var->ndims) if (var->ndims)

View File

@ -360,11 +360,11 @@ nc4_get_fill_value(NC_FILE_INFO_T *h5, NC_VAR_INFO_T *var, void **fillp)
* @param hdf_typeid Pointer that gets the HDF5 type ID. * @param hdf_typeid Pointer that gets the HDF5 type ID.
* @param endianness Desired endianness in HDF5 type. * @param endianness Desired endianness in HDF5 type.
* *
* @returns NC_NOERR No error. * @return NC_NOERR No error.
* @returns NC_ECHAR Conversions of NC_CHAR forbidden. * @return NC_ECHAR Conversions of NC_CHAR forbidden.
* @returns NC_EVARMETA HDF5 returning error creating datatype. * @return NC_EVARMETA HDF5 returning error creating datatype.
* @returns NC_EHDFERR HDF5 returning error. * @return NC_EHDFERR HDF5 returning error.
* @returns NC_EBADTYE Type not found. * @return NC_EBADTYE Type not found.
* @author Ed Hartnett * @author Ed Hartnett
*/ */
int int
@ -824,6 +824,10 @@ write_netcdf4_dimid(hid_t datasetid, int dimid)
* @param write_dimid True to write dimid. * @param write_dimid True to write dimid.
* *
* @return ::NC_NOERR * @return ::NC_NOERR
* @returns NC_ECHAR Conversions of NC_CHAR forbidden.
* @returns NC_EVARMETA HDF5 returning error creating datatype.
* @returns NC_EHDFERR HDF5 returning error.
* @returns NC_EBADTYE Type not found.
* @author Ed Hartnett * @author Ed Hartnett
*/ */
static int static int
@ -835,7 +839,7 @@ var_create_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, nc_bool_t write_dimid
void *fillp = NULL; void *fillp = NULL;
NC_DIM_INFO_T *dim = NULL; NC_DIM_INFO_T *dim = NULL;
char *name_to_use; char *name_to_use;
int retval = NC_NOERR; int retval;
LOG((3, "%s:: name %s", __func__, var->hdr.name)); LOG((3, "%s:: name %s", __func__, var->hdr.name));
@ -1052,7 +1056,6 @@ var_create_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, nc_bool_t write_dimid
BAIL(retval); BAIL(retval);
} }
/* Write attributes for this var. */ /* Write attributes for this var. */
if ((retval = write_attlist(var->att, var->hdr.id, grp))) if ((retval = write_attlist(var->att, var->hdr.id, grp)))
BAIL(retval); BAIL(retval);
@ -1135,6 +1138,11 @@ nc4_adjust_var_cache(NC_GRP_INFO_T *grp, NC_VAR_INFO_T * var)
* @param type Pointer to type info struct. * @param type Pointer to type info struct.
* *
* @return NC_NOERR No error. * @return NC_NOERR No error.
* @return NC_EHDFERR HDF5 error.
* @return NC_ECHAR Conversions of NC_CHAR forbidden.
* @return NC_EVARMETA HDF5 returning error creating datatype.
* @return NC_EHDFERR HDF5 returning error.
* @return NC_EBADTYE Type not found.
* @author Ed Hartnett * @author Ed Hartnett
*/ */
static int static int
@ -1162,7 +1170,8 @@ commit_type(NC_GRP_INFO_T *grp, NC_TYPE_INFO_T *type)
for(i=0;i<nclistlength(type->u.c.field);i++) for(i=0;i<nclistlength(type->u.c.field);i++)
{ {
if((field = (NC_FIELD_INFO_T*)nclistget(type->u.c.field,i)) == NULL) continue; field = (NC_FIELD_INFO_T *)nclistget(type->u.c.field, i);
assert(field);
if ((retval = nc4_get_hdf_typeid(grp->nc4_info, field->nc_typeid, if ((retval = nc4_get_hdf_typeid(grp->nc4_info, field->nc_typeid,
&hdf_base_typeid, type->endianness))) &hdf_base_typeid, type->endianness)))
return retval; return retval;
@ -2050,7 +2059,8 @@ nc4_rec_write_groups_types(NC_GRP_INFO_T *grp)
/* If there are any user-defined types, write them now. */ /* If there are any user-defined types, write them now. */
for(i=0;i<ncindexsize(grp->type);i++) { for(i=0;i<ncindexsize(grp->type);i++) {
if((type = (NC_TYPE_INFO_T*)ncindexith(grp->type,i)) == NULL) continue; type = (NC_TYPE_INFO_T *)ncindexith(grp->type, i);
assert(type);
if ((retval = commit_type(grp, type))) if ((retval = commit_type(grp, type)))
return retval; return retval;
} }

View File

@ -70,11 +70,6 @@ nc_initialize()
NC_initialized = 1; NC_initialized = 1;
NC_finalized = 0; NC_finalized = 0;
#ifdef _MSC_VER
/* Force binary mode */
_set_fmode(_O_BINARY);
#endif
/* Do general initialization */ /* Do general initialization */
if((stat = NCDISPATCH_initialize())) goto done; if((stat = NCDISPATCH_initialize())) goto done;

View File

@ -349,23 +349,13 @@ NC4_inq_attid(int ncid, int varid, const char *name, int *attnump)
int int
NC4_inq_attname(int ncid, int varid, int attnum, char *name) NC4_inq_attname(int ncid, int varid, int attnum, char *name)
{ {
NC *nc;
NC_ATT_INFO_T *att; NC_ATT_INFO_T *att;
NC_FILE_INFO_T *h5; int retval;
int retval = NC_NOERR;
LOG((2, "nc_inq_attname: ncid 0x%x varid %d attnum %d", LOG((2, "nc_inq_attname: ncid 0x%x varid %d attnum %d", ncid, varid,
ncid, varid, attnum)); attnum));
/* Find metadata. */ /* Find the attribute metadata. */
if (!(nc = nc4_find_nc_file(ncid,NULL)))
return NC_EBADID;
/* get netcdf-4 metadata */
h5 = NC4_DATA(nc);
assert(h5);
/* Handle netcdf-4 files. */
if ((retval = nc4_find_nc_att(ncid, varid, NULL, attnum, &att))) if ((retval = nc4_find_nc_att(ncid, varid, NULL, attnum, &att)))
return retval; return retval;

View File

@ -92,7 +92,7 @@ nc4_check_name(const char *name, char *norm_name)
* @param mode The mode flag. * @param mode The mode flag.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @author Ed Hartnett * @author Ed Hartnett, Dennis Heimbigner
*/ */
int int
nc4_nc4f_list_add(NC *nc, const char *path, int mode) nc4_nc4f_list_add(NC *nc, const char *path, int mode)
@ -101,8 +101,8 @@ nc4_nc4f_list_add(NC *nc, const char *path, int mode)
assert(nc && !NC4_DATA(nc) && path); assert(nc && !NC4_DATA(nc) && path);
/* We need to malloc and /* We need to malloc and initialize the substructure
initialize the substructure NC_HDF_FILE_INFO_T. */ NC_HDF_FILE_INFO_T. */
if (!(h5 = calloc(1, sizeof(NC_FILE_INFO_T)))) if (!(h5 = calloc(1, sizeof(NC_FILE_INFO_T))))
return NC_ENOMEM; return NC_ENOMEM;
nc->dispatchdata = h5; nc->dispatchdata = h5;
@ -115,6 +115,7 @@ nc4_nc4f_list_add(NC *nc, const char *path, int mode)
* types. */ * types. */
h5->next_typeid = NC_FIRSTUSERTYPEID; h5->next_typeid = NC_FIRSTUSERTYPEID;
/* Initialize lists for dimensions, types, and groups. */
h5->alldims = nclistnew(); h5->alldims = nclistnew();
h5->alltypes = nclistnew(); h5->alltypes = nclistnew();
h5->allgroups = nclistnew(); h5->allgroups = nclistnew();
@ -127,166 +128,82 @@ nc4_nc4f_list_add(NC *nc, const char *path, int mode)
/** /**
* @internal Given an ncid, find the relevant group and return a * @internal Given an ncid, find the relevant group and return a
* pointer to it, return an error of this is not a netcdf-4 file (or * pointer to it.
* if strict nc3 is turned on for this file.)
* *
* @param ncid File and group ID. * @param ncid File and group ID.
* @param grp Pointer that gets pointer to group info struct. * @param grp Pointer that gets pointer to group info struct. Ignored
* if NULL.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @return ::NC_ENOTNC4 Not a netCDF-4 file. * @return ::NC_ENOTNC4 Not a netCDF-4 file.
* @return ::NC_ESTRICTNC3 Not allowed for classic model.
* @author Ed Hartnett * @author Ed Hartnett
*/ */
int int
nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp) nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp)
{ {
NC_FILE_INFO_T* h5; return nc4_find_nc_grp_h5(ncid, NULL, grp, NULL);
NC *f = nc4_find_nc_file(ncid,&h5);
if(f == NULL) return NC_EBADID;
/* No netcdf-3 files allowed! */
if (!h5) return NC_ENOTNC4;
assert(h5->root_grp);
/* This function demands netcdf-4 files without strict nc3
* rules.*/
if (h5->cmode & NC_CLASSIC_MODEL) return NC_ESTRICTNC3;
/* If we can't find it, the grp id part of ncid is bad. */
if (!(*grp = nc4_rec_find_grp(h5, (ncid & GRP_ID_MASK))))
return NC_EBADID;
return NC_NOERR;
} }
/** /**
* @internal Given an ncid, find the relevant group and return a * @internal Given an ncid, find the relevant group and return a
* pointer to it, also set a pointer to the nc4_info struct of the * pointer to it, also set a pointer to the nc4_info struct of the
* related file. For netcdf-3 files, *h5 will be set to NULL. * related file.
* *
* @param ncid File and group ID. * @param ncid File and group ID.
* @param grpp Pointer that gets pointer to group info struct. * @param grp Pointer that gets pointer to group info struct. Ignored
* @param h5p Pointer to HDF5 file struct. * if NULL.
* @param h5 Pointer that gets pointer to file info struct. Ignored if
* NULL.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @return ::NC_EBADID Bad ncid. * @return ::NC_EBADID Bad ncid.
* @author Ed Hartnett * @author Ed Hartnett
*/ */
int int
nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grpp, NC_FILE_INFO_T **h5p) nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5)
{ {
NC_FILE_INFO_T *h5; return nc4_find_nc_grp_h5(ncid, NULL, grp, h5);
NC_GRP_INFO_T *grp;
NC *f = nc4_find_nc_file(ncid,&h5);
if(f == NULL) return NC_EBADID;
if (h5) {
assert(h5->root_grp);
/* If we can't find it, the grp id part of ncid is bad. */
if (!(grp = nc4_rec_find_grp(h5, (ncid & GRP_ID_MASK))))
return NC_EBADID;
h5 = (grp)->nc4_info;
assert(h5);
} else {
h5 = NULL;
grp = NULL;
}
if(h5p) *h5p = h5;
if(grpp) *grpp = grp;
return NC_NOERR;
} }
/** /**
* @internal Find info for this file and group, and set pointer to each. * @internal Find info for this file and group, and set pointers.
* *
* @param ncid File and group ID. * @param ncid File and group ID.
* @param nc Pointer that gets a pointer to the file's NC struct. * @param nc Pointer that gets a pointer to the file's NC
* @param grpp Pointer that gets a pointer to the group struct. * struct. Ignored if NULL.
* @param h5p Pointer that gets HDF5 file struct. * @param grp Pointer that gets a pointer to the group
* struct. Ignored if NULL.
* @param h5 Pointer that gets HDF5 file struct. Ignored if NULL.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @return ::NC_EBADID Bad ncid. * @return ::NC_EBADID Bad ncid.
* @author Ed Hartnett * @author Ed Hartnett, Dennis Heimbigner
*/ */
int int
nc4_find_nc_grp_h5(int ncid, NC **nc, NC_GRP_INFO_T **grpp, nc4_find_nc_grp_h5(int ncid, NC **nc, NC_GRP_INFO_T **grp, NC_FILE_INFO_T **h5)
NC_FILE_INFO_T **h5p)
{ {
NC_GRP_INFO_T *grp; NC_GRP_INFO_T *my_grp = NULL;
NC_FILE_INFO_T* h5; NC_FILE_INFO_T *my_h5 = NULL;
NC *f = nc4_find_nc_file(ncid,&h5); NC *my_nc;
int retval;
if(f == NULL) return NC_EBADID; /* Look up file metadata. */
if(nc) *nc = f; if ((retval = NC_check_id(ncid, &my_nc)))
return retval;
my_h5 = my_nc->dispatchdata;
assert(my_h5 && my_h5->root_grp);
if (h5) {
assert(h5->root_grp);
/* If we can't find it, the grp id part of ncid is bad. */ /* If we can't find it, the grp id part of ncid is bad. */
if (!(grp = nc4_rec_find_grp(h5, (ncid & GRP_ID_MASK)))) if (!(my_grp = nclistget(my_h5->allgroups, (ncid & GRP_ID_MASK))))
return NC_EBADID; return NC_EBADID;
h5 = (grp)->nc4_info; /* Return pointers to caller, if desired. */
assert(h5); if (nc)
} else { *nc = my_nc;
h5 = NULL; if (h5)
grp = NULL; *h5 = my_h5;
} if (grp)
if(h5p) *h5p = h5; *grp = my_grp;
if(grpp) *grpp = grp;
return NC_NOERR;
}
/**
* @internal Use NC_FILE_INFO_T->allgroups to locate a group id.
*
* @param h5 Pointer to file info
* @param target_nc_grpid Group ID to be found.
*
* @return Pointer to group info struct, or NULL if not found.
* @author Ed Hartnett
*/
NC_GRP_INFO_T *
nc4_rec_find_grp(NC_FILE_INFO_T *h5, int target_nc_grpid)
{
NC_GRP_INFO_T *g;
assert(h5);
/* Is this the group we are searching for? */
g = nclistget(h5->allgroups,target_nc_grpid);
return g;
}
/**
* @internal Given an ncid and varid, get pointers to the group and var
* metadata.
*
* @param nc Pointer to file's NC struct.
* @param ncid File ID.
* @param varid Variable ID.
* @param grp Pointer that gets pointer to group info.
* @param var Pointer that gets pointer to var info.
*
* @return ::NC_NOERR No error.
*/
int
nc4_find_g_var_nc(NC *nc, int ncid, int varid,
NC_GRP_INFO_T **grp, NC_VAR_INFO_T **var)
{
NC_FILE_INFO_T* h5 = NC4_DATA(nc);
/* Find the group info. */
assert(grp && var && h5 && h5->root_grp);
*grp = nc4_rec_find_grp(h5, (ncid & GRP_ID_MASK));
/* It is possible for *grp to be NULL. If it is,
return an error. */
if(*grp == NULL)
return NC_EBADID;
/* Find the var info. */
(*var) = (NC_VAR_INFO_T*)ncindexith((*grp)->vars,varid);
if((*var) == NULL)
return NC_ENOTVAR;
return NC_NOERR; return NC_NOERR;
} }
@ -310,22 +227,15 @@ int
nc4_find_grp_h5_var(int ncid, int varid, NC_FILE_INFO_T **h5, NC_GRP_INFO_T **grp, nc4_find_grp_h5_var(int ncid, int varid, NC_FILE_INFO_T **h5, NC_GRP_INFO_T **grp,
NC_VAR_INFO_T **var) NC_VAR_INFO_T **var)
{ {
NC *nc;
NC_FILE_INFO_T *my_h5; NC_FILE_INFO_T *my_h5;
NC_GRP_INFO_T *my_grp; NC_GRP_INFO_T *my_grp;
NC_VAR_INFO_T *my_var; NC_VAR_INFO_T *my_var;
int retval; int retval;
/* Find the NC from the ncid, and the h5 from that. */ /* Look up file and group metadata. */
if ((retval = NC_check_id(ncid, &nc))) if ((retval = nc4_find_grp_h5(ncid, &my_grp, &my_h5)))
return retval; return retval;
my_h5 = nc->dispatchdata; assert(my_grp && my_h5);
assert(nc && my_h5);
/* If we can't find it, the grp id part of ncid is bad. */
if (!(my_grp = nc4_rec_find_grp(my_h5, (ncid & GRP_ID_MASK))))
return NC_EBADID;
assert(my_grp);
/* Find the var. */ /* Find the var. */
if (!(my_var = (NC_VAR_INFO_T *)ncindexith(my_grp->vars, varid))) if (!(my_var = (NC_VAR_INFO_T *)ncindexith(my_grp->vars, varid)))
@ -349,7 +259,8 @@ nc4_find_grp_h5_var(int ncid, int varid, NC_FILE_INFO_T **h5, NC_GRP_INFO_T **gr
* @param grp Pointer to group info struct. * @param grp Pointer to group info struct.
* @param dimid Dimension ID to find. * @param dimid Dimension ID to find.
* @param dim Pointer that gets pointer to dim info if found. * @param dim Pointer that gets pointer to dim info if found.
* @param dim_grp Pointer that gets pointer to group info of group that contains dimension. * @param dim_grp Pointer that gets pointer to group info of group
* that contains dimension. Ignored if NULL.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @return ::NC_EBADDIM Dimension not found. * @return ::NC_EBADDIM Dimension not found.
@ -359,24 +270,12 @@ int
nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim, nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim,
NC_GRP_INFO_T **dim_grp) NC_GRP_INFO_T **dim_grp)
{ {
NC_GRP_INFO_T *g; assert(grp && grp->nc4_info && dim);
int found = 0;
NC_FILE_INFO_T* h5 = grp->nc4_info;
assert(h5 && grp && dim);
/* Find the dim info. */ /* Find the dim info. */
(*dim) = nclistget(h5->alldims,dimid); if (!((*dim) = nclistget(grp->nc4_info->alldims, dimid)))
if((*dim) == NULL)
return NC_EBADDIM; return NC_EBADDIM;
/* Redundant: Verify that this dim is in fact in the group or its parent */
for (found=0, g = grp; g ; g = g->parent) {
if(g == (*dim)->container) {found = 1; break;}
}
/* If we didn't find it, return an error. */
assert(found);
/* Give the caller the group the dimension is in. */ /* Give the caller the group the dimension is in. */
if (dim_grp) if (dim_grp)
*dim_grp = (*dim)->container; *dim_grp = (*dim)->container;
@ -411,7 +310,7 @@ nc4_find_var(NC_GRP_INFO_T *grp, const char *name, NC_VAR_INFO_T **var)
* @param name Name of type to find. * @param name Name of type to find.
* *
* @return Pointer to type info, or NULL if not found. * @return Pointer to type info, or NULL if not found.
* @author Ed Hartnett * @author Ed Hartnett, Dennis Heimbigner
*/ */
NC_TYPE_INFO_T * NC_TYPE_INFO_T *
nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name) nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name)
@ -438,23 +337,6 @@ nc4_rec_find_named_type(NC_GRP_INFO_T *start_grp, char *name)
return NULL; return NULL;
} }
/**
* @internal Recursively hunt for a netCDF type id.
* Note using h5->alltypes, we no longer do recursion
*
* @param h5 the root file
* @param target_nc_typeid NetCDF type ID to find.
*
* @return Pointer to type info, or NULL if not found.
* @author Ed Hartnett
*/
NC_TYPE_INFO_T *
nc4_rec_find_nc_type(NC_FILE_INFO_T *h5, nc_type target_nc_typeid)
{
assert(h5);
return nclistget(h5->alltypes, target_nc_typeid);
}
/** /**
* @internal Use a netCDF typeid to find a type in a type_list. * @internal Use a netCDF typeid to find a type in a type_list.
* *
@ -469,6 +351,8 @@ nc4_rec_find_nc_type(NC_FILE_INFO_T *h5, nc_type target_nc_typeid)
int int
nc4_find_type(const NC_FILE_INFO_T *h5, nc_type typeid, NC_TYPE_INFO_T **type) nc4_find_type(const NC_FILE_INFO_T *h5, nc_type typeid, NC_TYPE_INFO_T **type)
{ {
/* Check inputs. */
assert(h5);
if (typeid < 0 || !type) if (typeid < 0 || !type)
return NC_EINVAL; return NC_EINVAL;
*type = NULL; *type = NULL;
@ -479,9 +363,9 @@ nc4_find_type(const NC_FILE_INFO_T *h5, nc_type typeid, NC_TYPE_INFO_T **type)
return NC_NOERR; return NC_NOERR;
/* Find the type. */ /* Find the type. */
*type = (NC_TYPE_INFO_T*)nclistget(h5->alltypes,typeid); if (!(*type = nclistget(h5->alltypes,typeid)))
if((*type) == NULL)
return NC_EBADTYPID; return NC_EBADTYPID;
return NC_NOERR; return NC_NOERR;
} }
@ -538,14 +422,16 @@ nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum,
/* Now find the attribute by name or number. If a name is provided, /* Now find the attribute by name or number. If a name is provided,
* ignore the attnum. */ * ignore the attnum. */
if(attlist) { if (attlist)
NC_ATT_INFO_T* a; {
if(name != NULL) NC_ATT_INFO_T *my_att;
a = (NC_ATT_INFO_T*)ncindexlookup(attlist,name); if (name)
my_att = (NC_ATT_INFO_T *)ncindexlookup(attlist, name);
else else
a = (NC_ATT_INFO_T*)ncindexith(attlist,attnum); my_att = (NC_ATT_INFO_T *)ncindexith(attlist, attnum);
if(a != NULL) { if (my_att)
*att = a; {
*att = my_att;
return NC_NOERR; return NC_NOERR;
} }
} }
@ -575,46 +461,19 @@ nc4_find_nc_att(int ncid, int varid, const char *name, int attnum,
NC_ATT_INFO_T **att) NC_ATT_INFO_T **att)
{ {
NC_GRP_INFO_T *grp; NC_GRP_INFO_T *grp;
NC_FILE_INFO_T *h5;
int retval; int retval;
LOG((4, "nc4_find_nc_att: ncid 0x%x varid %d name %s attnum %d", LOG((4, "nc4_find_nc_att: ncid 0x%x varid %d name %s attnum %d",
ncid, varid, name, attnum)); ncid, varid, name, attnum));
/* Find info for this file and group, and set pointer to each. */ /* Find info for this file and group, and set pointer to each. */
if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) if ((retval = nc4_find_grp_h5(ncid, &grp, NULL)))
return retval; return retval;
assert(grp && h5); assert(grp);
return nc4_find_grp_att(grp, varid, name, attnum, att); return nc4_find_grp_att(grp, varid, name, attnum, att);
} }
/**
* @internal Given an id, walk the list and find the appropriate NC.
*
* @param ext_ncid File/group ID to find.
* @param h5p Pointer to pointer that gets the HDF5 file info struct.
*
* @return ::NC_NOERR No error.
* @author Ed Hartnett, Dennis Heimbigner
*/
NC*
nc4_find_nc_file(int ext_ncid, NC_FILE_INFO_T** h5p)
{
NC* nc;
int stat;
stat = NC_check_id(ext_ncid,&nc);
if(stat != NC_NOERR)
nc = NULL;
if(nc)
if(h5p) *h5p = (NC_FILE_INFO_T*)nc->dispatchdata;
return nc;
}
/** /**
* @internal Add NC_OBJ to allXXX lists in a file * @internal Add NC_OBJ to allXXX lists in a file
* *
@ -810,11 +669,12 @@ nc4_dim_list_add(NC_GRP_INFO_T *grp, const char *name, size_t len,
} }
/** /**
* @internal Add to the end of an att list. * @internal Add to an attribute list.
* *
* @param list NCindex of att info structs. * @param list NCindex of att info structs.
* @param name name of the new attribute * @param name name of the new attribute
* @param att Pointer to pointer that gets the new att info struct. * @param att Pointer to pointer that gets the new att info
* struct. Ignored if NULL.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @return ::NC_ENOMEM Out of memory. * @return ::NC_ENOMEM Out of memory.
@ -856,7 +716,8 @@ nc4_att_list_add(NCindex *list, const char *name, NC_ATT_INFO_T **att)
* @param parent Pointer to the parent group. Will be NULL when adding * @param parent Pointer to the parent group. Will be NULL when adding
* the root group. * the root group.
* @param name Name of the group. * @param name Name of the group.
* @param grp Pointer to pointer that gets new group info struct. * @param grp Pointer to pointer that gets new group info
* struct. Ignored if NULL.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @return ::NC_ENOMEM Out of memory. * @return ::NC_ENOMEM Out of memory.
@ -924,7 +785,7 @@ nc4_grp_list_add(NC_FILE_INFO_T *h5, NC_GRP_INFO_T *parent, char *name,
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @return ::NC_ENAMEINUSE Name is in use. * @return ::NC_ENAMEINUSE Name is in use.
* @author Ed Hartnett * @author Ed Hartnett, Dennis Heimbigner
*/ */
int int
nc4_check_dup_name(NC_GRP_INFO_T *grp, char *name) nc4_check_dup_name(NC_GRP_INFO_T *grp, char *name)
@ -996,7 +857,7 @@ nc4_type_new(NC_GRP_INFO_T *grp, size_t size, const char *name, int assignedid,
} }
/** /**
* @internal Add to the end of a type list. * @internal Add to the type list.
* *
* @param grp Pointer to group info struct. * @param grp Pointer to group info struct.
* @param size Size of type in bytes. * @param size Size of type in bytes.
@ -1038,7 +899,7 @@ nc4_type_list_add(NC_GRP_INFO_T *grp, size_t size, const char *name,
} }
/** /**
* @internal Add to the end of a compound field list. * @internal Add to the compound field list.
* *
* @param parent parent type * @param parent parent type
* @param name Name of the field. * @param name Name of the field.
@ -1050,7 +911,7 @@ nc4_type_list_add(NC_GRP_INFO_T *grp, size_t size, const char *name,
* @param dim_sizesp An array of dim sizes for the field. * @param dim_sizesp An array of dim sizes for the field.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @author Ed Hartnett * @author Ed Hartnett, Dennis Heimbigner
*/ */
int int
nc4_field_list_add(NC_TYPE_INFO_T *parent, const char *name, nc4_field_list_add(NC_TYPE_INFO_T *parent, const char *name,
@ -1171,7 +1032,8 @@ field_free(NC_FIELD_INFO_T *field)
* @param type Pointer to type info struct. * @param type Pointer to type info struct.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @author Ed Hartnett * @return ::NC_EHDFERR HDF5 error.
* @author Ed Hartnett, Dennis Heimbigner
*/ */
int int
nc4_type_free(NC_TYPE_INFO_T *type) nc4_type_free(NC_TYPE_INFO_T *type)
@ -1253,7 +1115,7 @@ nc4_type_free(NC_TYPE_INFO_T *type)
* @param var Pointer to the var info struct of var to delete. * @param var Pointer to the var info struct of var to delete.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @author Ed Hartnett * @author Ed Hartnett, Dennis Heimbigner
*/ */
int int
nc4_var_free(NC_VAR_INFO_T *var) nc4_var_free(NC_VAR_INFO_T *var)
@ -1344,7 +1206,7 @@ nc4_var_free(NC_VAR_INFO_T *var)
* @param var Pointer to the var info struct of var to delete. * @param var Pointer to the var info struct of var to delete.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @author Ed Hartnett * @author Ed Hartnett, Dennis Heimbigner
*/ */
int int
nc4_var_list_del(NC_GRP_INFO_T* grp, NC_VAR_INFO_T *var) nc4_var_list_del(NC_GRP_INFO_T* grp, NC_VAR_INFO_T *var)
@ -1411,14 +1273,12 @@ nc4_dim_list_del(NC_GRP_INFO_T* grp, NC_DIM_INFO_T *dim)
* @param grp Pointer to group info struct. * @param grp Pointer to group info struct.
* *
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @author Ed Hartnett * @author Ed Hartnett, Dennis Heimbigner
*/ */
int int
nc4_rec_grp_del(NC_GRP_INFO_T *grp) nc4_rec_grp_del(NC_GRP_INFO_T *grp)
{ {
NC_GRP_INFO_T *g;
NC_VAR_INFO_T *var; NC_VAR_INFO_T *var;
NC_ATT_INFO_T *att;
NC_DIM_INFO_T *dim; NC_DIM_INFO_T *dim;
int retval; int retval;
int i; int i;
@ -1426,38 +1286,30 @@ nc4_rec_grp_del(NC_GRP_INFO_T *grp)
assert(grp); assert(grp);
LOG((3, "%s: grp->name %s", __func__, grp->hdr.name)); LOG((3, "%s: grp->name %s", __func__, grp->hdr.name));
/* WARNING: for all these deletes, the nc4_xxx_del /* WARNING: for all these deletes, the nc4_xxx_del functions will
functions will modify the index, so we need to modify the index, so we need to not assume any state about
not assume any state about them. them. */
*/
/* Recursively call this function for each child, if any, stopping /* Recursively call this function for each child, if any, stopping
* if there is an error. */ * if there is an error. */
for(i=0;i<ncindexsize(grp->children);i++) { for (i = 0; i < ncindexsize(grp->children); i++)
g = (NC_GRP_INFO_T*)ncindexith(grp->children,i); if ((retval = nc4_rec_grp_del((NC_GRP_INFO_T *)ncindexith(grp->children,
if(g == NULL) continue; i))))
if ((retval = nc4_rec_grp_del(g)))
return retval; return retval;
}
ncindexfree(grp->children); ncindexfree(grp->children);
grp->children = NULL; grp->children = NULL;
/* Delete all the list contents for vars, dims, and atts, in this /* Free attributes, but leave in parent list */
* group. */ for (i = 0; i < ncindexsize(grp->att); i++)
for(i=0;i<ncindexsize(grp->att);i++) { if ((retval = nc4_att_free((NC_ATT_INFO_T *)ncindexith(grp->att, i))))
att = (NC_ATT_INFO_T*)ncindexith(grp->att,i);
if(att == NULL) continue;
LOG((4, "%s: deleting att %s", __func__, att->hdr.name));
if ((retval = nc4_att_free(att))) /* free but leave in parent list */
return retval; return retval;
}
ncindexfree(grp->att); ncindexfree(grp->att);
grp->att = NULL; grp->att = NULL;
/* Delete all vars. */ /* Delete all vars. */
for (i = 0; i < ncindexsize(grp->vars); i++) { for (i = 0; i < ncindexsize(grp->vars); i++) {
var = (NC_VAR_INFO_T *)ncindexith(grp->vars,i); var = (NC_VAR_INFO_T *)ncindexith(grp->vars,i);
if(var == NULL) continue; assert(var);
LOG((4, "%s: deleting var %s", __func__, var->hdr.name)); LOG((4, "%s: deleting var %s", __func__, var->hdr.name));
/* Close HDF5 dataset associated with this var, unless it's a /* Close HDF5 dataset associated with this var, unless it's a
* scale. */ * scale. */
@ -1471,13 +1323,14 @@ nc4_rec_grp_del(NC_GRP_INFO_T *grp)
return retval; return retval;
} }
ncindexfree(grp->vars); ncindexfree(grp->vars);
grp->vars = NULL;
/* Delete all dims. */ /* Delete all dims. */
for(i=0;i<ncindexsize(grp->dim);i++) { for (i = 0; i < ncindexsize(grp->dim); i++)
{
dim = (NC_DIM_INFO_T *)ncindexith(grp->dim, i); dim = (NC_DIM_INFO_T *)ncindexith(grp->dim, i);
if(dim == NULL) continue; assert(dim);
LOG((4, "%s: deleting dim %s", __func__, dim->hdr.name)); LOG((4, "%s: deleting dim %s", __func__, dim->hdr.name));
/* If this is a dim without a coordinate variable, then close /* If this is a dim without a coordinate variable, then close
* the HDF5 DIM_WITHOUT_VARIABLE dataset associated with this * the HDF5 DIM_WITHOUT_VARIABLE dataset associated with this
* dim. */ * dim. */
@ -1487,29 +1340,29 @@ nc4_rec_grp_del(NC_GRP_INFO_T *grp)
return retval; return retval;
} }
ncindexfree(grp->dim); ncindexfree(grp->dim);
grp->dim = NULL;
/* Delete all types. */ /* Delete all types. */
/* Is this code correct? I think it should do repeated passes /* Is this code correct? I think it should do repeated passes
over h5->alltypes using the ref count to decide what to delete */ over h5->alltypes using the ref count to decide what to delete */
for(i=0;i<ncindexsize(grp->type);i++) { for (i = 0; i < ncindexsize(grp->type); i++)
{
NC_TYPE_INFO_T *type = (NC_TYPE_INFO_T *)ncindexith(grp->type, i); NC_TYPE_INFO_T *type = (NC_TYPE_INFO_T *)ncindexith(grp->type, i);
if(type == NULL) continue; assert(type);
LOG((4, "%s: deleting type %s", __func__, type->hdr.name)); LOG((4, "%s: deleting type %s", __func__, type->hdr.name));
if ((retval = nc4_type_free(type))) /* free but leave in parent list */ if ((retval = nc4_type_free(type))) /* free but leave in parent list */
return retval; return retval;
} }
ncindexfree(grp->type); ncindexfree(grp->type);
grp->type = NULL;
/* Tell HDF5 we're closing this group. */ /* Tell HDF5 we're closing this group. */
LOG((4, "%s: closing group %s", __func__, grp->hdr.name)); LOG((4, "%s: closing group %s", __func__, grp->hdr.name));
if (grp->hdf_grpid && H5Gclose(grp->hdf_grpid) < 0) if (grp->hdf_grpid && H5Gclose(grp->hdf_grpid) < 0)
return NC_EHDFERR; return NC_EHDFERR;
/* Free up this group */
/* Free the name. */ /* Free the name. */
free(grp->hdr.name); free(grp->hdr.name);
/* Free up this group */
free(grp); free(grp);
return NC_NOERR; return NC_NOERR;
@ -1779,23 +1632,24 @@ rec_print_metadata(NC_GRP_INFO_T *grp, int tab_count)
* useful to check that netCDF is working! Nonetheless, this function * useful to check that netCDF is working! Nonetheless, this function
* will print nothing if logging is not set to at least two. * will print nothing if logging is not set to at least two.
* *
* @param Pointer to the file info struct.
*
* @return ::NC_NOERR No error. * @return ::NC_NOERR No error.
* @author Ed Hartnett * @author Ed Hartnett
*/ */
int int
log_metadata_nc(NC *nc) log_metadata_nc(NC_FILE_INFO_T *h5)
{ {
NC_FILE_INFO_T *h5 = NC4_DATA(nc);
LOG((2, "*** NetCDF-4 Internal Metadata: int_ncid 0x%x ext_ncid 0x%x", LOG((2, "*** NetCDF-4 Internal Metadata: int_ncid 0x%x ext_ncid 0x%x",
nc->int_ncid, nc->ext_ncid)); h5->root_grp->nc4_info->controller->int_ncid,
h5->root_grp->nc4_info->controller->ext_ncid));
if (!h5) if (!h5)
{ {
LOG((2, "This is a netCDF-3 file.")); LOG((2, "This is a netCDF-3 file."));
return NC_NOERR; return NC_NOERR;
} }
LOG((2, "FILE - path: %s cmode: 0x%x parallel: %d redef: %d " LOG((2, "FILE - path: %s cmode: 0x%x parallel: %d redef: %d "
"fill_mode: %d no_write: %d next_nc_grpid: %d", nc->path, "fill_mode: %d no_write: %d next_nc_grpid: %d", h5->root_grp->nc4_info->controller->path,
h5->cmode, (int)h5->parallel, (int)h5->redef, h5->fill_mode, (int)h5->no_write, h5->cmode, (int)h5->parallel, (int)h5->redef, h5->fill_mode, (int)h5->no_write,
h5->next_nc_grpid)); h5->next_nc_grpid));
if(nc_log_level >= 2) if(nc_log_level >= 2)
@ -1821,16 +1675,16 @@ NC4_show_metadata(int ncid)
{ {
int retval = NC_NOERR; int retval = NC_NOERR;
#ifdef LOGGING #ifdef LOGGING
NC *nc; NC_FILE_INFO_T *h5;
int old_log_level = nc_log_level; int old_log_level = nc_log_level;
/* Find file metadata. */ /* Find file metadata. */
if (!(nc = nc4_find_nc_file(ncid,NULL))) if ((retval = nc4_find_grp_h5(ncid, NULL, &h5)))
return NC_EBADID; return retval;
/* Log level must be 2 to see metadata. */ /* Log level must be 2 to see metadata. */
nc_log_level = 2; nc_log_level = 2;
retval = log_metadata_nc(nc); retval = log_metadata_nc(h5);
nc_log_level = old_log_level; nc_log_level = old_log_level;
#endif /*LOGGING*/ #endif /*LOGGING*/
return retval; return retval;

View File

@ -123,7 +123,7 @@ NC4_inq_type(int ncid, nc_type typeid1, char *name, size_t *size)
return retval; return retval;
/* Find this type. */ /* Find this type. */
if (!(type = nc4_rec_find_nc_type(grp->nc4_info, typeid1))) if (!(type = nclistget(grp->nc4_info->alltypes, typeid1)))
return NC_EBADTYPE; return NC_EBADTYPE;
if (name) if (name)
@ -173,7 +173,7 @@ NC4_inq_user_type(int ncid, nc_type typeid1, char *name, size_t *size,
return retval; return retval;
/* Find this type. */ /* Find this type. */
if (!(type = nc4_rec_find_nc_type(grp->nc4_info, typeid1))) if (!(type = nclistget(grp->nc4_info->alltypes, typeid1)))
return NC_EBADTYPE; return NC_EBADTYPE;
/* Count the number of fields. */ /* Count the number of fields. */
@ -252,13 +252,13 @@ NC4_inq_compound_field(int ncid, nc_type typeid1, int fieldid, char *name,
return retval; return retval;
/* Find this type. */ /* Find this type. */
if (!(type = nc4_rec_find_nc_type(grp->nc4_info, typeid1))) if (!(type = nclistget(grp->nc4_info->alltypes, typeid1)))
return NC_EBADTYPE; return NC_EBADTYPE;
/* Find the field. */ /* Find the field. */
field = (NC_FIELD_INFO_T*)nclistget(type->u.c.field,fieldid); if (!(field = nclistget(type->u.c.field,fieldid)))
if(field) return NC_EBADFIELD;
{
if (name) if (name)
strcpy(name, field->hdr.name); strcpy(name, field->hdr.name);
if (offsetp) if (offsetp)
@ -270,36 +270,6 @@ NC4_inq_compound_field(int ncid, nc_type typeid1, int fieldid, char *name,
if (dim_sizesp) if (dim_sizesp)
for (d = 0; d < field->ndims; d++) for (d = 0; d < field->ndims; d++)
dim_sizesp[d] = field->dim_size[d]; dim_sizesp[d] = field->dim_size[d];
return NC_NOERR;
}
return NC_EBADFIELD;
}
/**
* @internal Find a netcdf-4 file. THis will return an error if it
* finds a netcdf-3 file, or a netcdf-4 file with strict nc3 rules.
*
* @param ncid File and group ID.
* @param nc Pointer to pointer that gets NC struct for file.
*
* @return ::NC_NOERR No error.
* @return ::NC_EBADID Bad ncid.
* @return ::NC_ESTRICTNC3 File uses classic model.
* @author Ed Hartnett
*/
static int
find_nc4_file(int ncid, NC **nc)
{
NC_FILE_INFO_T *h5;
/* Find file metadata. */
if (!((*nc) = nc4_find_nc_file(ncid, &h5)))
return NC_EBADID;
assert(h5);
if (h5->cmode & NC_CLASSIC_MODEL)
return NC_ESTRICTNC3;
return NC_NOERR; return NC_NOERR;
} }
@ -321,7 +291,7 @@ find_nc4_file(int ncid, NC **nc)
int int
NC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fieldidp) NC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fieldidp)
{ {
NC *nc; NC_FILE_INFO_T *h5;
NC_TYPE_INFO_T *type; NC_TYPE_INFO_T *type;
NC_FIELD_INFO_T *field; NC_FIELD_INFO_T *field;
char norm_name[NC_MAX_NAME + 1]; char norm_name[NC_MAX_NAME + 1];
@ -332,11 +302,11 @@ NC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fi
ncid, typeid1, name)); ncid, typeid1, name));
/* Find file metadata. */ /* Find file metadata. */
if ((retval = find_nc4_file(ncid, &nc))) if ((retval = nc4_find_grp_h5(ncid, NULL, &h5)))
return retval; return retval;
/* Find the type. */ /* Find the type. */
if ((retval = nc4_find_type(NC4_DATA(nc), typeid1, &type))) if ((retval = nc4_find_type(h5, typeid1, &type)))
return retval; return retval;
/* Did the user give us a good compound type typeid? */ /* Did the user give us a good compound type typeid? */
@ -348,8 +318,10 @@ NC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fi
return retval; return retval;
/* Find the field with this name. */ /* Find the field with this name. */
for(i=0;i<nclistlength(type->u.c.field);i++) { for (i = 0; i < nclistlength(type->u.c.field); i++)
if((field = (NC_FIELD_INFO_T*)nclistget(type->u.c.field,i)) == NULL) continue; {
field = nclistget(type->u.c.field, i);
assert(field);
if (!strcmp(field->hdr.name, norm_name)) if (!strcmp(field->hdr.name, norm_name))
break; break;
field = NULL; /* because this is the indicator of not found */ field = NULL; /* because this is the indicator of not found */
@ -396,7 +368,7 @@ NC4_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier)
return retval; return retval;
/* Find this type. */ /* Find this type. */
if (!(type = nc4_rec_find_nc_type(grp->nc4_info, xtype))) if (!(type = nclistget(grp->nc4_info->alltypes, xtype)))
return NC_EBADTYPE; return NC_EBADTYPE;
/* Complain if they are confused about the type. */ /* Complain if they are confused about the type. */
@ -406,7 +378,8 @@ NC4_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier)
/* Move to the desired enum member in the list. */ /* Move to the desired enum member in the list. */
for (found = 0, i = 0; i < nclistlength(type->u.e.enum_member); i++) for (found = 0, i = 0; i < nclistlength(type->u.e.enum_member); i++)
{ {
if((enum_member = (NC_ENUM_MEMBER_INFO_T*)nclistget(type->u.e.enum_member,i)) == NULL) continue; enum_member = nclistget(type->u.e.enum_member, i);
assert(enum_member);
switch (type->u.e.base_nc_typeid) switch (type->u.e.base_nc_typeid)
{ {
case NC_BYTE: case NC_BYTE:
@ -483,7 +456,7 @@ NC4_inq_enum_member(int ncid, nc_type typeid1, int idx, char *identifier,
return retval; return retval;
/* Find this type. */ /* Find this type. */
if (!(type = nc4_rec_find_nc_type(grp->nc4_info, typeid1))) if (!(type = nclistget(grp->nc4_info->alltypes, typeid1)))
return NC_EBADTYPE; return NC_EBADTYPE;
/* Complain if they are confused about the type. */ /* Complain if they are confused about the type. */
@ -491,9 +464,7 @@ NC4_inq_enum_member(int ncid, nc_type typeid1, int idx, char *identifier,
return NC_EBADTYPE; return NC_EBADTYPE;
/* Move to the desired enum member in the list. */ /* Move to the desired enum member in the list. */
/* Check index. */ if (!(enum_member = nclistget(type->u.e.enum_member, idx)))
enum_member = (NC_ENUM_MEMBER_INFO_T*)nclistget(type->u.e.enum_member,idx);
if(enum_member == NULL)
return NC_EINVAL; return NC_EINVAL;
/* Give the people what they want. */ /* Give the people what they want. */

View File

@ -395,40 +395,35 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
int int
nc_inq_var_chunking_ints(int ncid, int varid, int *contiguousp, int *chunksizesp) nc_inq_var_chunking_ints(int ncid, int varid, int *contiguousp, int *chunksizesp)
{ {
NC *nc;
NC_GRP_INFO_T *grp;
NC_VAR_INFO_T *var; NC_VAR_INFO_T *var;
NC_FILE_INFO_T *h5;
size_t *cs = NULL; size_t *cs = NULL;
int i, retval; int i, retval;
/* Find this ncid's file info. */ /* Get pointer to the var. */
if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) if ((retval = nc4_find_grp_h5_var(ncid, varid, NULL, NULL, &var)))
return retval;
assert(nc);
/* Find var cause I need the number of dims. */
if ((retval = nc4_find_g_var_nc(nc, ncid, varid, &grp, &var)))
return retval; return retval;
assert(var);
/* Allocate space for the size_t copy of the chunksizes array. */ /* Allocate space for the size_t copy of the chunksizes array. */
if (var->ndims) if (var->ndims)
if (!(cs = malloc(var->ndims * sizeof(size_t)))) if (!(cs = malloc(var->ndims * sizeof(size_t))))
return NC_ENOMEM; return NC_ENOMEM;
/* Call the netcdf-4 version directly. */
retval = NC4_inq_var_all(ncid, varid, NULL, NULL, NULL, NULL, NULL, retval = NC4_inq_var_all(ncid, varid, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, contiguousp, cs, NULL, NULL, NULL, NULL, NULL, contiguousp, cs, NULL,
NULL, NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL, NULL);
/* Copy from size_t array. */ /* Copy from size_t array. */
if (chunksizesp && var->contiguous == NC_CHUNKED) if (!retval && chunksizesp && var->contiguous == NC_CHUNKED)
{
for (i = 0; i < var->ndims; i++) for (i = 0; i < var->ndims; i++)
{ {
chunksizesp[i] = (int)cs[i]; chunksizesp[i] = (int)cs[i];
if (cs[i] > NC_MAX_INT) if (cs[i] > NC_MAX_INT)
retval = NC_ERANGE; retval = NC_ERANGE;
} }
}
if (var->ndims) if (var->ndims)
free(cs); free(cs);

View File

@ -31,8 +31,8 @@
int int
NC4_inq_format(int ncid, int *formatp) NC4_inq_format(int ncid, int *formatp)
{ {
NC *nc;
NC_FILE_INFO_T *nc4_info; NC_FILE_INFO_T *nc4_info;
int retval;
LOG((2, "nc_inq_format: ncid 0x%x", ncid)); LOG((2, "nc_inq_format: ncid 0x%x", ncid));
@ -40,11 +40,10 @@ NC4_inq_format(int ncid, int *formatp)
return NC_NOERR; return NC_NOERR;
/* Find the file metadata. */ /* Find the file metadata. */
if (!(nc = nc4_find_nc_file(ncid,&nc4_info))) if ((retval = nc4_find_nc_grp_h5(ncid, NULL, NULL, &nc4_info)))
return NC_EBADID; return retval;
/* Otherwise, this is a netcdf-4 file. Check if classic NC3 rules /* Check if classic NC3 rules are in effect for this file. */
* are in effect for this file. */
if (nc4_info->cmode & NC_CLASSIC_MODEL) if (nc4_info->cmode & NC_CLASSIC_MODEL)
*formatp = NC_FORMAT_NETCDF4_CLASSIC; *formatp = NC_FORMAT_NETCDF4_CLASSIC;
else else
@ -73,15 +72,15 @@ int
NC4_inq_format_extended(int ncid, int *formatp, int *modep) NC4_inq_format_extended(int ncid, int *formatp, int *modep)
{ {
NC *nc; NC *nc;
NC_FILE_INFO_T *h5; int retval;
LOG((2, "%s: ncid 0x%x", __func__, ncid)); LOG((2, "%s: ncid 0x%x", __func__, ncid));
/* Find the file metadata. */ if ((retval = nc4_find_nc_grp_h5(ncid, &nc, NULL, NULL)))
if (!(nc = nc4_find_nc_file(ncid,&h5)))
return NC_EBADID; return NC_EBADID;
if(modep) *modep = (nc->mode|NC_NETCDF4); if(modep)
*modep = nc->mode|NC_NETCDF4;
if (formatp) if (formatp)
*formatp = NC_FORMATX_NC_HDF5; *formatp = NC_FORMATX_NC_HDF5;

View File

@ -62,7 +62,7 @@ main(int argc, char **argv)
SUMMARIZE_ERR; SUMMARIZE_ERR;
printf("*** testing HDF5 file with circular group structure..."); printf("*** testing HDF5 file with circular group structure...");
{ {
hid_t hdfid, grpid, grpid2, fapl_id; hid_t hdfid, grpid, grpid2;
int ncid; int ncid;
/* First use HDF5 to create a file with circular group /* First use HDF5 to create a file with circular group