diff --git a/include/hdf4dispatch.h b/include/hdf4dispatch.h index 36b9766935..c8dcffee71 100644 --- a/include/hdf4dispatch.h +++ b/include/hdf4dispatch.h @@ -40,7 +40,7 @@ extern "C" { extern int NC_HDF4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, - void *parameters, const NC_Dispatch *, NC *); + void *parameters, const NC_Dispatch *, int); extern int NC_HDF4_abort(int ncid); diff --git a/include/nc3dispatch.h b/include/nc3dispatch.h index bab7318319..998ee4314d 100644 --- a/include/nc3dispatch.h +++ b/include/nc3dispatch.h @@ -53,13 +53,13 @@ extern "C" { extern int NC3_create(const char *path, int cmode, size_t initialsz, int basepe, size_t *chunksizehintp, - void* mpidata, const struct NC_Dispatch*, NC* ncp); + void* mpidata, const struct NC_Dispatch*, int ncid); /* WARNING: this signature differs from external nc_open API*/ extern int NC3_open(const char *path, int mode, int basepe, size_t *chunksizehintp, - void* mpidata, const NC_Dispatch*, NC* ncp); + void* mpidata, const NC_Dispatch*, int ncid); extern int NC3_new_nc(NC**); diff --git a/include/nc4dispatch.h b/include/nc4dispatch.h index 75bc3f9893..65f9518398 100644 --- a/include/nc4dispatch.h +++ b/include/nc4dispatch.h @@ -23,12 +23,12 @@ extern "C" { EXTERNL int NC4_create(const char *path, int cmode, size_t initialsz, int basepe, size_t *chunksizehintp, - void* parameters, const NC_Dispatch*, NC*); + void* parameters, const NC_Dispatch*, int); EXTERNL int NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, - void* parameters, const NC_Dispatch*, NC*); + void* parameters, const NC_Dispatch*, int); EXTERNL int NC4_redef(int ncid); diff --git a/include/nc4internal.h b/include/nc4internal.h index e0c076aa9c..51a6f4218b 100644 --- a/include/nc4internal.h +++ b/include/nc4internal.h @@ -334,6 +334,8 @@ int nc4_get_typeclass(const NC_FILE_INFO_T *h5, nc_type xtype, int nc4_type_free(NC_TYPE_INFO_T *type); /* These list functions add and delete vars, atts. */ +int nc4_file_list_add(int ncid, const char *path, int mode, + void **dispatchdata); int nc4_nc4f_list_add(NC *nc, const char *path, int mode); int nc4_nc4f_list_del(NC_FILE_INFO_T *h5); int nc4_var_list_add(NC_GRP_INFO_T* grp, const char* name, int ndims, diff --git a/include/netcdf_dispatch.h b/include/netcdf_dispatch.h index fedb072d94..63040d2d0b 100644 --- a/include/netcdf_dispatch.h +++ b/include/netcdf_dispatch.h @@ -25,9 +25,9 @@ struct NC_Dispatch int (*create)(const char *path, int cmode, size_t initialsz, int basepe, size_t *chunksizehintp, void *parameters, - const struct NC_Dispatch *table, NC *ncp); + const struct NC_Dispatch *table, int ncid); int (*open)(const char *path, int mode, int basepe, size_t *chunksizehintp, - void *parameters, const struct NC_Dispatch *table, NC *ncp); + void *parameters, const struct NC_Dispatch *table, int ncid); int (*redef)(int); int (*_enddef)(int,size_t,size_t,size_t,size_t); @@ -140,7 +140,7 @@ struct NC_Dispatch EXTERNL int NC_RO_create(const char *path, int cmode, size_t initialsz, int basepe, size_t *chunksizehintp, void* parameters, - const NC_Dispatch*, NC*); + const NC_Dispatch*, int); EXTERNL int NC_RO_redef(int ncid); EXTERNL int NC_RO__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align); diff --git a/libdap2/ncd2dispatch.c b/libdap2/ncd2dispatch.c index 0b2d81d233..1299f91431 100644 --- a/libdap2/ncd2dispatch.c +++ b/libdap2/ncd2dispatch.c @@ -63,7 +63,7 @@ static NCerror applyclientparams(NCDAPCOMMON*); static int NCD2_create(const char *path, int cmode, size_t initialsz, int basepe, size_t *chunksizehintp, - void* mpidata, const struct NC_Dispatch*,NC* ncp); + void* mpidata, const struct NC_Dispatch*,int); static int NCD2_redef(int ncid); static int NCD2__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align); @@ -227,7 +227,7 @@ NCD2_abort(int ncid) static int NCD2_create(const char *path, int cmode, size_t initialsz, int basepe, size_t *chunksizehintp, - void* mpidata, const NC_Dispatch* dispatch, NC* ncp) + void* mpidata, const NC_Dispatch* dispatch, int ncid) { return NC_EPERM; } @@ -271,14 +271,19 @@ NCD2_get_vars(int ncid, int varid, /* See ncd2dispatch.c for other version */ int NCD2_open(const char* path, int mode, int basepe, size_t *chunksizehintp, - void* mpidata, const NC_Dispatch* dispatch, NC* drno) + void* mpidata, const NC_Dispatch* dispatch, int ncid) { NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; NCDAPCOMMON* dapcomm = NULL; + NC* drno; const char* value; int nc3id = -1; + /* Find pointer to NC struct for this file. */ + ncstat = NC_check_id(ncid,&drno); + if(ncstat != NC_NOERR) {goto done;} + if(path == NULL) {ncstat = NC_EDAPURL; goto done;} if(dispatch == NULL) diff --git a/libdap2/ncd2dispatch.h b/libdap2/ncd2dispatch.h index 902fd9df30..d0947ab091 100644 --- a/libdap2/ncd2dispatch.h +++ b/libdap2/ncd2dispatch.h @@ -46,7 +46,7 @@ extern "C" { extern int NCD2_open(const char *path, int mode, int basepe, size_t *chunksizehintp, - void* mpidata, const struct NC_Dispatch* dispatch, NC* ncp); + void* mpidata, const struct NC_Dispatch* dispatch, int ncid); extern int NCD2_close(int ncid,void*); diff --git a/libdap4/d4file.c b/libdap4/d4file.c index 401550d9a8..3d68761c14 100644 --- a/libdap4/d4file.c +++ b/libdap4/d4file.c @@ -38,18 +38,23 @@ static const char* checkseps = "+,:;"; int NCD4_open(const char * path, int mode, int basepe, size_t *chunksizehintp, - void *mpidata, const NC_Dispatch *dispatch, NC *nc) + void *mpidata, const NC_Dispatch *dispatch, int ncid) { int ret = NC_NOERR; NCD4INFO* d4info = NULL; const char* value; NCD4meta* meta; + NC* nc; if(path == NULL) return THROW(NC_EDAPURL); assert(dispatch != NULL); + /* Find pointer to NC struct for this file. */ + ret = NC_check_id(ncid,&nc); + if(ret != NC_NOERR) {goto done;} + /* Setup our NC and NCDAPCOMMON state*/ d4info = (NCD4INFO*)calloc(1,sizeof(NCD4INFO)); diff --git a/libdap4/ncd4dispatch.c b/libdap4/ncd4dispatch.c index e6f9405d57..a91b68934f 100644 --- a/libdap4/ncd4dispatch.c +++ b/libdap4/ncd4dispatch.c @@ -85,7 +85,7 @@ NCD4_sync(int ncid) static int NCD4_create(const char *path, int cmode, size_t initialsz, int basepe, size_t *chunksizehintp, - void* mpidata, const NC_Dispatch *dispatch, NC *ncp) + void* mpidata, const NC_Dispatch *dispatch, int ncid) { return THROW(NC_EPERM); } diff --git a/libdap4/ncd4dispatch.h b/libdap4/ncd4dispatch.h index 8513a75e27..d3aadbbcab 100644 --- a/libdap4/ncd4dispatch.h +++ b/libdap4/ncd4dispatch.h @@ -17,7 +17,7 @@ extern "C" { extern int NCD4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, - void *mpidata, const struct NC_Dispatch *dispatch, NC *ncp); + void *mpidata, const struct NC_Dispatch *dispatch, int ncid); extern int NCD4_close(int ncid,void*); diff --git a/libdispatch/dfile.c b/libdispatch/dfile.c index 0d4eecaf97..f74c2dd242 100644 --- a/libdispatch/dfile.c +++ b/libdispatch/dfile.c @@ -1901,7 +1901,7 @@ NC_create(const char *path0, int cmode, size_t initialsz, /* Assume create will fill in remaining ncp fields */ if ((stat = dispatcher->create(ncp->path, cmode, initialsz, basepe, chunksizehintp, - parameters, dispatcher, ncp))) { + parameters, dispatcher, ncp->ext_ncid))) { del_from_NCList(ncp); /* oh well */ free_NC(ncp); } else { @@ -2090,12 +2090,12 @@ NC_open(const char *path0, int omode, int basepe, size_t *chunksizehintp, /* Create the NC* instance and insert its dispatcher */ if((stat = new_NC(dispatcher,path,omode,&model,&ncp))) goto done; - /* Add to list of known open files */ + /* Add to list of known open files. This assignes an ext_ncid. */ add_to_NCList(ncp); /* Assume open will fill in remaining ncp fields */ stat = dispatcher->open(ncp->path, omode, basepe, chunksizehintp, - parameters, dispatcher, ncp); + parameters, dispatcher, ncp->ext_ncid); if(stat == NC_NOERR) { if(ncidp) *ncidp = ncp->ext_ncid; } else { diff --git a/libdispatch/dreadonly.c b/libdispatch/dreadonly.c index 6cf9e48bee..f8c03ffb5e 100644 --- a/libdispatch/dreadonly.c +++ b/libdispatch/dreadonly.c @@ -245,7 +245,7 @@ NC_RO_sync(int ncid) * @param use_parallel Ignored. * @param parameters Ignored. * @param dispatch Ignored. - * @param nc_file Ignored. + * @param ncid Ignored. * * @return ::NC_EPERM Cannot create files. * @author Ed Hartnett @@ -253,7 +253,7 @@ NC_RO_sync(int ncid) int NC_RO_create(const char* path, int cmode, size_t initialsz, int basepe, size_t *chunksizehintp, void *parameters, - const NC_Dispatch *dispatch, NC *nc_file) + const NC_Dispatch *dispatch, int ncid) { return NC_EPERM; } diff --git a/libhdf4/hdf4file.c b/libhdf4/hdf4file.c index d78f59176f..2cc120ac13 100644 --- a/libhdf4/hdf4file.c +++ b/libhdf4/hdf4file.c @@ -597,20 +597,25 @@ hdf4_read_var(NC_FILE_INFO_T *h5, int v) */ int NC_HDF4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, - void *parameters, const NC_Dispatch *dispatch, NC *nc_file) + void *parameters, const NC_Dispatch *dispatch, int ncid) { NC_FILE_INFO_T *h5; NC_HDF4_FILE_INFO_T *hdf4_file; + NC *nc; int32 num_datasets, num_gatts; int32 sdid; int v, a; int retval; /* Check inputs. */ - assert(nc_file && path); + assert(path); LOG((1, "%s: path %s mode %d params %x", __func__, path, mode, parameters)); + /* Find pointer to NC. */ + if ((retval = NC_check_id(ncid, &nc))) + return retval; + /* Check the mode for validity */ if (mode & ILLEGAL_OPEN_FLAGS) return NC_EINVAL; @@ -624,9 +629,8 @@ NC_HDF4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, return NC_EHDFERR; /* Add necessary structs to hold netcdf-4 file data. */ - if ((retval = nc4_nc4f_list_add(nc_file, path, mode))) + if ((retval = nc4_file_list_add(ncid, path, mode, (void **)&h5))) return retval; - h5 = (NC_FILE_INFO_T *)nc_file->dispatchdata; assert(h5 && h5->root_grp); h5->no_write = NC_TRUE; h5->root_grp->atts_read = 1; diff --git a/libhdf5/hdf5create.c b/libhdf5/hdf5create.c index 66fa0ac230..39b3f3a614 100644 --- a/libhdf5/hdf5create.c +++ b/libhdf5/hdf5create.c @@ -27,9 +27,10 @@ extern int NC4_create_image_file(NC_FILE_INFO_T* h5, size_t); * * @param path The file name of the new file. * @param cmode The creation mode flag. - * @param initialsz The proposed initial file size (advisory) - * @param parameters extra parameter info (like MPI communicator) - * @param nc Pointer to an instance of NC. + * @param initialsz The proposed initial file size (advisory, for + * in-memory netCDF-4/HDF5 files only). + * @param parameters extra parameter info (like MPI communicator). + * @param ncid The already-assigned ncid for this file (aka ext_ncid). * * @return ::NC_NOERR No error. * @return ::NC_EINVAL Invalid input (check cmode). @@ -40,13 +41,13 @@ extern int NC4_create_image_file(NC_FILE_INFO_T* h5, size_t); */ static int nc4_create_file(const char *path, int cmode, size_t initialsz, - void* parameters, NC *nc) + void* parameters, int ncid) { hid_t fcpl_id, fapl_id = -1; unsigned flags; FILE *fp; int retval = NC_NOERR; - NC_FILE_INFO_T* nc4_info = NULL; + NC_FILE_INFO_T *nc4_info; NC_HDF5_FILE_INFO_T *hdf5_info; NC_HDF5_GRP_INFO_T *hdf5_grp; @@ -58,13 +59,13 @@ nc4_create_file(const char *path, int cmode, size_t initialsz, int info_duped = 0; /* Whether the MPI Info object was duplicated */ #endif /* !USE_PARALLEL4 */ - assert(nc && path); + assert(path); LOG((3, "%s: path %s mode 0x%x", __func__, path, cmode)); /* Add necessary structs to hold netcdf-4 file data. */ - if ((retval = nc4_nc4f_list_add(nc, path, (NC_WRITE | cmode)))) + if ((retval = nc4_file_list_add(ncid, path, NC_WRITE | cmode, + (void **)&nc4_info))) BAIL(retval); - nc4_info = NC4_DATA(nc); assert(nc4_info && nc4_info->root_grp); nc4_info->root_grp->atts_read = 1; @@ -261,7 +262,8 @@ nc4_create_file(const char *path, int cmode, size_t initialsz, * @param parameters pointer to struct holding extra data (e.g. for * parallel I/O) layer. Ignored if NULL. * @param dispatch Pointer to the dispatch table for this file. - * @param nc_file Pointer to an instance of NC. + * @param ncid The ncid that has been assigned by the dispatch layer + * (aka ext_ncid). * * @return ::NC_NOERR No error. * @return ::NC_EINVAL Invalid input (check cmode). @@ -271,11 +273,11 @@ nc4_create_file(const char *path, int cmode, size_t initialsz, int NC4_create(const char* path, int cmode, size_t initialsz, int basepe, size_t *chunksizehintp, void *parameters, - const NC_Dispatch *dispatch, NC *nc_file) + const NC_Dispatch *dispatch, int ncid) { int res; - assert(nc_file && path); + assert(path); LOG((1, "%s: path %s cmode 0x%x parameters %p", __func__, path, cmode, parameters)); @@ -290,16 +292,13 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe, hdf5_set_log_level(); #endif /* LOGGING */ - /* Check the cmode for validity. */ - if((cmode & ILLEGAL_CREATE_FLAGS) != 0) - {res = NC_EINVAL; goto done;} + /* Check the cmode for validity. Checking parallel against + * NC_DISKLESS already done in NC_create(). */ + if (cmode & ILLEGAL_CREATE_FLAGS) + return NC_EINVAL; - /* check parallel against NC_DISKLESS already done in NC_create() */ + /* Create the netCDF-4/HDF5 file. */ + res = nc4_create_file(path, cmode, initialsz, parameters, ncid); - nc_file->int_ncid = nc_file->ext_ncid; - - res = nc4_create_file(path, cmode, initialsz, parameters, nc_file); - -done: return res; } diff --git a/libhdf5/hdf5open.c b/libhdf5/hdf5open.c index 1b11855290..06d97a65b4 100644 --- a/libhdf5/hdf5open.c +++ b/libhdf5/hdf5open.c @@ -622,7 +622,7 @@ check_for_classic_model(NC_GRP_INFO_T *root_grp, int *is_classic) * @param path The file name of the new file. * @param mode The open mode flag. * @param parameters File parameters. - * @param nc Pointer to NC file info. + * @param ncid The ncid that has been assigned to this file. * * @return ::NC_NOERR No error. * @return ::NC_ENOMEM Out of memory. @@ -634,30 +634,36 @@ check_for_classic_model(NC_GRP_INFO_T *root_grp, int *is_classic) * @author Ed Hartnett, Dennis Heimbigner */ static int -nc4_open_file(const char *path, int mode, void* parameters, NC *nc) +nc4_open_file(const char *path, int mode, void* parameters, int ncid) { + NC_FILE_INFO_T *nc4_info = NULL; + NC_HDF5_FILE_INFO_T *h5 = NULL; + NC *nc; hid_t fapl_id = H5P_DEFAULT; - int retval; unsigned flags; - NC_FILE_INFO_T *nc4_info = NULL; int is_classic; - NC_HDF5_FILE_INFO_T *h5 = NULL; - #ifdef USE_PARALLEL4 - NC_MPI_INFO* mpiinfo = NULL; + NC_MPI_INFO *mpiinfo = NULL; int comm_duped = 0; /* Whether the MPI Communicator was duplicated */ int info_duped = 0; /* Whether the MPI Info object was duplicated */ #endif + int retval; LOG((3, "%s: path %s mode %d", __func__, path, mode)); - assert(path && nc); + assert(path); + + /* Find pointer to NC. */ + if ((retval = NC_check_id(ncid, &nc))) + return retval; + assert(nc && nc->model->impl == NC_FORMATX_NC4); + /* Determine the HDF5 open flag to use. */ flags = (mode & NC_WRITE) ? H5F_ACC_RDWR : H5F_ACC_RDONLY; /* Add necessary structs to hold netcdf-4 file data. */ if ((retval = nc4_nc4f_list_add(nc, path, mode))) BAIL(retval); - nc4_info = NC4_DATA(nc); + nc4_info = (NC_FILE_INFO_T *)nc->dispatchdata; assert(nc4_info && nc4_info->root_grp); /* Add struct to hold HDF5-specific file metadata. */ @@ -673,12 +679,12 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc) #ifdef ENABLE_BYTERANGE /* See if we want the byte range protocol */ if(nc->model->iosp == NC_IOSP_HTTP) { - h5->http.iosp = 1; - /* Kill off any conflicting modes flags */ - mode &= ~(NC_WRITE|NC_DISKLESS|NC_PERSIST|NC_INMEMORY); - parameters = NULL; /* kill off parallel */ + h5->http.iosp = 1; + /* Kill off any conflicting modes flags */ + mode &= ~(NC_WRITE|NC_DISKLESS|NC_PERSIST|NC_INMEMORY); + parameters = NULL; /* kill off parallel */ } else - h5->http.iosp = 0; + h5->http.iosp = 0; #endif /*ENABLE_BYTERANGE*/ nc4_info->mem.inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY); @@ -687,7 +693,7 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc) /* Does the mode specify that this file is read-only? */ if ((mode & NC_WRITE) == 0) - nc4_info->no_write = NC_TRUE; + nc4_info->no_write = NC_TRUE; if(nc4_info->mem.inmemory && nc4_info->mem.diskless) BAIL(NC_EINTERNAL); @@ -748,76 +754,76 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc) /* Process NC_INMEMORY */ if(nc4_info->mem.inmemory) { - NC_memio* memio; - /* validate */ - if(parameters == NULL) - BAIL(NC_EINMEMORY); - memio = (NC_memio*)parameters; - if(memio->memory == NULL || memio->size == 0) + NC_memio* memio; + /* validate */ + if(parameters == NULL) + BAIL(NC_EINMEMORY); + memio = (NC_memio*)parameters; + if(memio->memory == NULL || memio->size == 0) BAIL(NC_EINMEMORY); - /* initialize h5->mem */ - nc4_info->mem.memio = *memio; - /* Is the incoming memory locked? */ - nc4_info->mem.locked = (nc4_info->mem.memio.flags & NC_MEMIO_LOCKED) == NC_MEMIO_LOCKED; - /* As a safeguard, if not locked and not read-only, - then we must take control of the incoming memory */ - if(!nc4_info->mem.locked && !nc4_info->no_write) { + /* initialize h5->mem */ + nc4_info->mem.memio = *memio; + /* Is the incoming memory locked? */ + nc4_info->mem.locked = (nc4_info->mem.memio.flags & NC_MEMIO_LOCKED) == NC_MEMIO_LOCKED; + /* As a safeguard, if not locked and not read-only, + then we must take control of the incoming memory */ + if(!nc4_info->mem.locked && !nc4_info->no_write) { memio->memory = NULL; /* take control */ memio->size = 0; - } - retval = NC4_open_image_file(nc4_info); - if(retval) + } + retval = NC4_open_image_file(nc4_info); + if(retval) BAIL(NC_EHDFERR); } else - if(nc4_info->mem.diskless) { /* Process NC_DISKLESS */ - size_t min_incr = 65536; /* Minimum buffer increment */ - /* Configure FAPL to use the core file driver */ - if (H5Pset_fapl_core(fapl_id, min_incr, (nc4_info->mem.persist?1:0)) < 0) - BAIL(NC_EHDFERR); - /* Open the HDF5 file. */ - if ((h5->hdfid = H5Fopen(path, flags, fapl_id)) < 0) - BAIL(NC_EHDFERR); - } + if(nc4_info->mem.diskless) { /* Process NC_DISKLESS */ + size_t min_incr = 65536; /* Minimum buffer increment */ + /* Configure FAPL to use the core file driver */ + if (H5Pset_fapl_core(fapl_id, min_incr, (nc4_info->mem.persist?1:0)) < 0) + BAIL(NC_EHDFERR); + /* Open the HDF5 file. */ + if ((h5->hdfid = H5Fopen(path, flags, fapl_id)) < 0) + BAIL(NC_EHDFERR); + } #ifdef ENABLE_BYTERANGE - else - if(h5->http.iosp) { /* Arrange to use the byte-range driver */ - /* Configure FAPL to use the byte-range file driver */ - if (H5Pset_fapl_http(fapl_id) < 0) - BAIL(NC_EHDFERR); - /* Open the HDF5 file. */ - if ((h5->hdfid = H5Fopen(path, flags, fapl_id)) < 0) - BAIL(NC_EHDFERR); - } + else + if(h5->http.iosp) { /* Arrange to use the byte-range driver */ + /* Configure FAPL to use the byte-range file driver */ + if (H5Pset_fapl_http(fapl_id) < 0) + BAIL(NC_EHDFERR); + /* Open the HDF5 file. */ + if ((h5->hdfid = H5Fopen(path, flags, fapl_id)) < 0) + BAIL(NC_EHDFERR); + } #endif - else - { - /* Open the HDF5 file. */ - if ((h5->hdfid = H5Fopen(path, flags, fapl_id)) < 0) - BAIL(NC_EHDFERR); - } + else + { + /* Open the HDF5 file. */ + if ((h5->hdfid = H5Fopen(path, flags, fapl_id)) < 0) + BAIL(NC_EHDFERR); + } /* Now read in all the metadata. Some types and dimscale * information may be difficult to resolve here, if, for example, a * dataset of user-defined type is encountered before the * definition of that type. */ if ((retval = rec_read_metadata(nc4_info->root_grp))) - BAIL(retval); + BAIL(retval); /* Check for classic model attribute. */ if ((retval = check_for_classic_model(nc4_info->root_grp, &is_classic))) - BAIL(retval); + BAIL(retval); if (is_classic) - nc4_info->cmode |= NC_CLASSIC_MODEL; + nc4_info->cmode |= NC_CLASSIC_MODEL; /* Set the provenance info for this file */ if ((retval = NC4_read_provenance(nc4_info))) - BAIL(retval); + BAIL(retval); /* Now figure out which netCDF dims are indicated by the dimscale * information. */ if ((retval = rec_match_dimscales(nc4_info->root_grp))) - BAIL(retval); + BAIL(retval); #ifdef LOGGING /* This will print out the names, types, lens, etc of the vars and @@ -862,10 +868,9 @@ nc4_open_file(const char *path, int mode, void* parameters, NC *nc) */ int NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, - void *parameters, const NC_Dispatch *dispatch, NC *nc_file) + void *parameters, const NC_Dispatch *dispatch, int ncid) { - assert(nc_file && path && dispatch && nc_file && - nc_file->model->impl == NC_FORMATX_NC4); + assert(path && dispatch); LOG((1, "%s: path %s mode %d params %x", __func__, path, mode, parameters)); @@ -887,10 +892,8 @@ NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp, hdf5_set_log_level(); #endif /* LOGGING */ - nc_file->int_ncid = nc_file->ext_ncid; - /* Open the file. */ - return nc4_open_file(path, mode, parameters, nc_file); + return nc4_open_file(path, mode, parameters, ncid); } /** diff --git a/libsrc/nc3internal.c b/libsrc/nc3internal.c index b52a6e3623..dc0bdc5e67 100644 --- a/libsrc/nc3internal.c +++ b/libsrc/nc3internal.c @@ -1039,13 +1039,18 @@ int NC3_new_nc(NC3_INFO** ncpp) int NC3_create(const char *path, int ioflags, size_t initialsz, int basepe, size_t *chunksizehintp, void *parameters, - const NC_Dispatch *dispatch, NC *nc) + const NC_Dispatch *dispatch, int ncid) { int status = NC_NOERR; void *xp = NULL; int sizeof_off_t = 0; + NC *nc; NC3_INFO* nc3 = NULL; + /* Find NC struct for this file. */ + if ((status = NC_check_id(ncid, &nc))) + return status; + /* Create our specific NC3_INFO instance */ nc3 = new_NC3INFO(chunksizehintp); @@ -1171,10 +1176,15 @@ nc_set_default_format(int format, int *old_formatp) int NC3_open(const char *path, int ioflags, int basepe, size_t *chunksizehintp, - void *parameters, const NC_Dispatch *dispatch, NC *nc) + void *parameters, const NC_Dispatch *dispatch, int ncid) { int status; NC3_INFO* nc3 = NULL; + NC *nc; + + /* Find NC struct for this file. */ + if ((status = NC_check_id(ncid, &nc))) + return status; /* Create our specific NC3_INFO instance */ nc3 = new_NC3INFO(chunksizehintp); diff --git a/libsrc4/nc4internal.c b/libsrc4/nc4internal.c index c57a8b1b42..461419c83c 100644 --- a/libsrc4/nc4internal.c +++ b/libsrc4/nc4internal.c @@ -82,9 +82,54 @@ nc4_check_name(const char *name, char *norm_name) return NC_NOERR; } +/** + * @internal Add a file to the list of libsrc4 open files. This is + * used by dispatch layers that wish to use the libsrc4 metadata + * model, but don't know about struct NC. This is the same as + * nc4_nc4f_list_add(), except it takes an ncid instead of an NC *, + * and also passes back the dispatchdata pointer. + * + * @param ncid The ncid of the file (aka ext_ncid). + * @param path The file name of the new file. + * @param mode The mode flag. + * @param dispatchdata Void * that gets pointer to dispatch data, + * which is the NC_FILE_INFO_T struct allocated for this file and its + * metadata. Ignored if NULL. (This is passed as a void to allow + * external user-defined formats to use this function.) + * + * @return ::NC_NOERR No error. + * @return ::NC_EBADID No NC struct with this ext_ncid. + * @return ::NC_ENOMEM Out of memory. + * @author Ed Hartnett + */ +int +nc4_file_list_add(int ncid, const char *path, int mode, void **dispatchdata) +{ + NC *nc; + int ret; + + /* Find NC pointer for this file. */ + if ((ret = NC_check_id(ncid, &nc))) + return ret; + + /* Add necessary structs to hold netcdf-4 file data. This is where + * the NC_FILE_INFO_T struct is allocated for the file. */ + if ((ret = nc4_nc4f_list_add(nc, path, mode))) + return ret; + + /* If the user wants a pointer to the NC_FILE_INFO_T, then provide + * it. */ + if (dispatchdata) + *dispatchdata = nc->dispatchdata; + + return NC_NOERR; +} + /** * @internal Given an NC pointer, add the necessary stuff for a - * netcdf-4 file. + * netcdf-4 file. This allocates the NC_FILE_INFO_T struct for the + * file, which is used by libhdf5 and libhdf4 (and perhaps other + * future dispatch layers) to hold the metadata for the file. * * @param nc Pointer to file's NC struct. * @param path The file name of the new file. @@ -103,7 +148,7 @@ nc4_nc4f_list_add(NC *nc, const char *path, int mode) assert(nc && !NC4_DATA(nc) && path); /* We need to malloc and initialize the substructure - NC_HDF_FILE_INFO_T. */ + NC_FILE_INFO_T. */ if (!(h5 = calloc(1, sizeof(NC_FILE_INFO_T)))) return NC_ENOMEM; nc->dispatchdata = h5; diff --git a/libsrcp/ncpdispatch.c b/libsrcp/ncpdispatch.c index af0fafff45..1fde2c4784 100644 --- a/libsrcp/ncpdispatch.c +++ b/libsrcp/ncpdispatch.c @@ -45,10 +45,15 @@ NCP_create(const char *path, size_t *chunksizehintp, void *mpidata, const struct NC_Dispatch *table, - NC *nc) + int ncid) { int status; NCP_INFO *nc5; + NC *nc; + + /* Find pointer to NC for this file. */ + status = NC_check_id(ncid, &nc); + if (status != NC_NOERR) return status; /* Check the cmode for only valid flags */ if (cmode & ~LEGAL_CREATE_FLAGS) return NC_EINVAL; @@ -82,10 +87,15 @@ NCP_open(const char *path, size_t *chunksizehintp, void *mpidata, const struct NC_Dispatch *table, - NC *nc) + int ncid) { int status; NCP_INFO *nc5; + NC *nc; + + /* Find pointer to NC for this file. */ + status = NC_check_id(ncid, &nc); + if (status != NC_NOERR) return status; /* Check the omode for only valid flags */ if (omode & ~LEGAL_OPEN_FLAGS) return NC_EINVAL; diff --git a/nc_test4/tst_udf.c b/nc_test4/tst_udf.c index 64fefb0308..534d3be42d 100644 --- a/nc_test4/tst_udf.c +++ b/nc_test4/tst_udf.c @@ -26,7 +26,7 @@ NC4_show_metadata(int ncid) int tst_open(const char *path, int mode, int basepe, size_t *chunksizehintp, - void *parameters, const NC_Dispatch *dispatch, NC *nc_file) + void *parameters, const NC_Dispatch *dispatch, int ncid) { return NC_NOERR; }