added function give_var_secret_name()

This commit is contained in:
Ed Hartnett 2019-01-27 11:06:02 -07:00
parent 42c64598dc
commit 627a55cf78
3 changed files with 50 additions and 15 deletions

View File

@ -135,7 +135,10 @@ int nc4_reform_coord_var(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *coord_var, NC_DIM_IN
extern hid_t NC4_image_init(NC_FILE_INFO_T* h5);
extern void NC4_image_finalize(void*);
/* These functions are internal to the libhdf5 directory. */
/* Create HDF5 dataset for dim without a coord var. */
extern int nc4_create_dim_wo_var(NC_DIM_INFO_T *dim);
/* Get the fill value for a var. */
int nc4_get_fill_value(NC_FILE_INFO_T *h5, NC_VAR_INFO_T *var, void **fillp);

View File

@ -220,6 +220,36 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
return NC_NOERR;
}
/**
* @internal Give a var a secret HDF5 name. This is needed when a var
* is defined with the same name as a dim, but it is not a coord var
* of that dim. In that case, the var uses a secret name inside the
* HDF5 file.
*
* @param var Pointer to var info.
* @param name Non-secret name. Should already be UTF8 normalized.
*
* @returns ::NC_NOERR No error.
* @returns ::NC_EMAXNAME Name too long to fit secret prefix.
* @returns ::NC_ENOMEM Out of memory.
* @author Ed Hartnett
*/
static int
give_var_secret_name(NC_VAR_INFO_T *var, const char *name)
{
/* Set a different hdf5 name for this variable to avoid name
* clash. */
if (strlen(name) + strlen(NON_COORD_PREPEND) > NC_MAX_NAME)
return NC_EMAXNAME;
if (!(var->hdf5_name = malloc((strlen(NON_COORD_PREPEND) +
strlen(name) + 1) * sizeof(char))))
return NC_ENOMEM;
sprintf(var->hdf5_name, "%s%s", NON_COORD_PREPEND, name);
return NC_NOERR;
}
/**
* @internal This is called when a new netCDF-4 variable is defined
* with nc_def_var().
@ -502,17 +532,8 @@ NC4_def_var(int ncid, const char *name, nc_type xtype,
* and this var has the same name. */
dim = (NC_DIM_INFO_T*)ncindexlookup(grp->dim,norm_name);
if (dim && (!var->ndims || dimidsp[0] != dim->hdr.id))
{
/* Set a different hdf5 name for this variable to avoid name
* clash. */
if (strlen(norm_name) + strlen(NON_COORD_PREPEND) > NC_MAX_NAME)
BAIL(NC_EMAXNAME);
if (!(var->hdf5_name = malloc((strlen(NON_COORD_PREPEND) +
strlen(norm_name) + 1) * sizeof(char))))
BAIL(NC_ENOMEM);
sprintf(var->hdf5_name, "%s%s", NON_COORD_PREPEND, norm_name);
}
if ((retval = give_var_secret_name(var, norm_name)))
BAIL(retval);
/* If this is a coordinate var, it is marked as a HDF5 dimension
* scale. (We found dim above.) Otherwise, allocate space to
@ -1039,6 +1060,7 @@ NC4_rename_var(int ncid, int varid, const char *name)
NC_HDF5_GRP_INFO_T *hdf5_grp;
NC_FILE_INFO_T *h5;
NC_VAR_INFO_T *var;
NC_DIM_INFO_T *other_dim;
int retval = NC_NOERR;
if (!name)
@ -1082,6 +1104,16 @@ NC4_rename_var(int ncid, int varid, const char *name)
(h5->cmode & NC_CLASSIC_MODEL))
return NC_ENOTINDEFINE;
/* Is there another dim with this name, for which this var will not
* be a coord var? If so, we have to create a dim without a
* variable for the old name. */
if ((other_dim = (NC_DIM_INFO_T *)ncindexlookup(grp->dim, name)) &&
strcmp(name, var->dim[0]->hdr.name))
{
if ((retval = nc4_create_dim_wo_var(other_dim)))
return retval;
}
/* Change the HDF5 file, if this var has already been created
there. */
if (var->created)

View File

@ -1720,8 +1720,8 @@ write_var(NC_VAR_INFO_T *var, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
* @returns ::NC_EHDFERR HDF5 returned error.
* @author Ed Hartnett
*/
static int
create_dim_wo_var(NC_DIM_INFO_T *dim)
int
nc4_create_dim_wo_var(NC_DIM_INFO_T *dim)
{
NC_HDF5_DIM_INFO_T *hdf5_dim;
NC_HDF5_GRP_INFO_T *hdf5_grp;
@ -1821,7 +1821,7 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
* variable. (That is, it should appear as a dimension
* without an associated variable.) */
if (!hdf5_dim->hdf_dimscaleid)
if ((retval = create_dim_wo_var(dim)))
if ((retval = nc4_create_dim_wo_var(dim)))
BAIL(retval);
/* Did we extend an unlimited dimension? */