Added the necessary code to support

group renaming. The primary API
is 'nc_rename_grp(int grpid, const char* name)'.
No test cases provided yet.
This also required adding a rename_grp entry
to the dispatch tables.
This commit is contained in:
Dennis Heimbigner 2013-07-19 21:48:37 +00:00
parent 1c23ec06b8
commit b85d3568ec
13 changed files with 128 additions and 6 deletions

View File

@ -234,6 +234,7 @@ typedef struct NC_GRP_INFO
int natts;
struct NC_HDF5_FILE_INFO *nc4_info;
char *name;
char *old_name; /* need when renaming group */
hid_t hdf_grpid;
NC_TYPE_INFO_T *type;
} NC_GRP_INFO_T;

View File

@ -291,6 +291,7 @@ int (*inq_dimids)(int, int* ndims, int*, int);
int (*inq_typeids)(int, int* ntypes, int*);
int (*inq_type_equal)(int, nc_type, int, nc_type, int*);
int (*def_grp)(int, const char*, int*);
int (*rename_grp)(int, const char*);
int (*inq_user_type)(int, nc_type, char*, size_t*, nc_type*, size_t*, int*);
int (*inq_typeid)(int, const char*, nc_type*);

View File

@ -517,6 +517,10 @@ nc_inq_type_equal(int ncid1, nc_type typeid1, int ncid2,
EXTERNL int
nc_def_grp(int parent_ncid, const char *name, int *new_ncid);
/* Rename a group */
EXTERNL int
nc_rename_group(int ncid, int grpid, const char *name);
/* Here are functions for dealing with compound types. */
/* Create a compound type. */

View File

@ -104,6 +104,7 @@ NULL, /*inq_dimids*/
NULL, /*inq_typeids*/
NULL, /*inq_type_equal*/
NULL, /*def_grp*/
NULL, /*rename_grp*/
NULL, /*inq_user_type*/
NULL, /*inq_typeid*/

View File

@ -47,7 +47,7 @@ Groups are identified with a ncid, which identifies both the open
file, and the group within that file. When a file is opened with
nc_open or nc_create, the ncid for the root group of that file is
provided. Using that as a starting point, users can add new groups, or
list and navigate existing groups.
list and navigate existing groups or rename a group.
All netCDF calls take a ncid which determines where the call will take
its action. For example, the nc_def_var function takes a ncid as its
@ -173,7 +173,14 @@ nc_def_grp(int parent_ncid, const char *name, int *new_ncid)
return ncp->dispatch->def_grp(parent_ncid,name,new_ncid);
}
int
nc_rename_grp(int grpid, const char *name)
{
NC* ncp;
int stat = NC_check_id(grpid,&ncp);
if(stat != NC_NOERR) return stat;
return ncp->dispatch->rename_grp(grpid,name);
}
int
nc_show_metadata(int ncid)

View File

@ -571,6 +571,17 @@ NCSUB_def_grp(int ncid, const char* a1, int* a2)
return ncsub->dispatch->def_grp(nc->substrate,a1,a2);
}
static int
NCSUB_rename_grp(int ncid, const char* a2)
{
NC *nc, *ncsub;
int ncstat = NC_check_id(ncid, &nc);
if(ncstat != NC_NOERR) return ncstat;
ncstat = NC_check_id(nc->substrate, &ncsub);
if(ncstat != NC_NOERR) return ncstat;
return ncsub->dispatch->rename_grp(nc->substrate,a2);
}
static int
NCSUB_inq_user_type(int ncid, nc_type a1, char* a2, size_t* a3, nc_type* a4, size_t* a5, int* a6)
{
@ -881,6 +892,7 @@ NCSUB_inq_dimids,
NCSUB_inq_typeids,
NCSUB_inq_type_equal,
NCSUB_def_grp,
NCSUB_rename_grp,
NCSUB_inq_user_type,
NCSUB_inq_typeid,

View File

@ -53,6 +53,7 @@ static int NC3_inq_dimids(int,int* ndims,int*,int);
static int NC3_inq_typeids(int,int* ntypes,int*);
static int NC3_inq_type_equal(int,nc_type,int,nc_type,int*);
static int NC3_def_grp(int,const char*,int*);
static int NC3_rename_grp(int,const char*);
static int NC3_inq_user_type(int,nc_type,char*,size_t*,nc_type*,size_t*,int*);
static int NC3_inq_typeid(int,const char*,nc_type*);
static int NC3_def_compound(int,size_t,const char*,nc_type*);
@ -139,6 +140,7 @@ NC3_inq_dimids,
NC3_inq_typeids,
NC3_inq_type_equal,
NC3_def_grp,
NC3_rename_grp,
NC3_inq_user_type,
NC3_inq_typeid,
@ -227,6 +229,12 @@ NC3_def_grp(int parent_ncid, const char *name, int *new_ncid)
return NC_ENOTNC4;
}
static int
NC3_rename_grp(int grpid, const char *name)
{
return NC_ENOTNC4;
}
static int
NC3_inq_ncid(int ncid, const char *name, int *grp_ncid)
{

View File

@ -72,6 +72,7 @@ NC4_inq_dimids,
NC4_inq_typeids,
NC4_inq_type_equal,
NC4_def_grp,
NC4_rename_grp,
NC4_inq_user_type,
NC4_inq_typeid,

View File

@ -187,6 +187,9 @@ NC4_inq_type_equal(int, nc_type, int, nc_type, int *);
EXTERNL int
NC4_def_grp(int, const char *, int *);
EXTERNL int
NC4_rename_grp(int, const char *);
EXTERNL int
NC4_inq_user_type(int, nc_type, char *, size_t *, nc_type *,
size_t *, int *);

View File

@ -61,6 +61,68 @@ NC4_def_grp(int parent_ncid, const char *name, int *new_ncid)
return NC_NOERR;
}
/* Rename a group. */
int
NC4_rename_grp(int grpid, const char *name)
{
NC_GRP_INFO_T *grp, *g;
NC_HDF5_FILE_INFO_T *h5;
char norm_name[NC_MAX_NAME + 1];
int retval;
LOG((2, "nc_rename_grp: grpid 0x%x name %s", grpid, name));
/* Find info for this file and group, and set pointer to each. */
if ((retval = nc4_find_grp_h5(grpid, &grp, &h5)))
return retval;
if (!h5)
return NC_ENOTNC4;
if (h5->no_write)
return NC_EPERM; /* attempt to write to a read-only file */
/* Do not allow renaming the root group */
if(grp->parent == NULL)
return NC_EBADGRPID;
/* Check and normalize the name. */
if ((retval = nc4_check_name(name, norm_name)))
return retval;
/* Check that this name is not in use as a var, grp, or type. */
if ((retval = nc4_check_dup_name(grp, norm_name)))
return retval;
/* If it's not in define mode, switch to define mode. */
if (!(h5->flags & NC_INDEF))
if ((retval = NC4_redef(grpid)))
return retval;
/* Save the old name, we'll need it to rename this object when we
* sync to HDF5 file. But if there already is an old_name saved,
* just stick with what we've got, since the user might be renaming
* the crap out of this thing, without ever syncing with the
* file. When the sync does take place, we only need the original
* name of the grp, not any of the intermediate ones. If the user
* could just make up his mind, we could all get on to writing some
* data... */
if (!grp->old_name)
{
if (!(grp->old_name = malloc((strlen(grp->name) + 1) * sizeof(char))))
return NC_ENOMEM;
strcpy(grp->old_name, grp->name);
}
/* Give the group its new name in metadata. UTF8 normalization
* has been done. */
free(grp->name);
if (!(grp->name = malloc((strlen(norm_name) + 1) * sizeof(char))))
return NC_ENOMEM;
strcpy(grp->name, norm_name);
return NC_NOERR;
}
/* Given an ncid and group name (NULL gets root group), return
* the ncid of that group. */
int

View File

@ -2554,6 +2554,16 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, int bad_coord_order)
if ((retval = attach_dimscales(grp)))
return retval;
/* Rename this group */
if (grp->old_name && strlen(grp->old_name))
{
/* Rename the group in the HDF5 file. */
if (H5Gmove(grp->hdf_grpid, grp->old_name, grp->name) < 0)
return NC_EHDFERR;
/* Reset old_name. */
strcpy(grp->old_name, "");
}
/* If there are any child groups, write their metadata. */
for (child_grp = grp->children; child_grp; child_grp = child_grp->next)
if ((retval = nc4_rec_write_metadata(child_grp, bad_coord_order)))

View File

@ -798,6 +798,12 @@ NC5_def_grp(int parent_ncid, const char *name, int *new_ncid)
return NC_ENOTNC4;
}
static int
NC5_rename_grp(int ncid, const char *name)
{
return NC_ENOTNC4;
}
static int
NC5_inq_ncid(int ncid, const char *name, int *grp_ncid)
{
@ -1098,6 +1104,7 @@ NC5_inq_dimids,
NC5_inq_typeids,
NC5_inq_type_equal,
NC5_def_grp,
NC5_rename_grp,
NC5_inq_user_type,
NC5_inq_typeid,

View File

@ -1,9 +1,9 @@
# Test c output
T=niltest
T=scope
#VG=valgrind --leak-check=full
#STDLIB=/usr/local
STDLIB=/share/ed/local/${HOST}
STDLIB=/usr/local
#STDLIB=/share/ed/local/${HOST}
CFLAGS=-I../include -I${STDLIB}/include
LDFLAGS=../liblib/.libs/libnetcdf.a -L${STDLIB}/lib -lhdf5_hl -lhdf5 -lz -lm -lcurl
@ -23,7 +23,12 @@ ctest::
../ncdump/ncdump ./${T}.nc >${T}.dmp
diff -wBb ${T}.cdl ${T}.dmp
ct::
gtest::
./ncgen -k3 -lc ${T}.cdl >${T}.c
gcc -g -O0 -o ${T} ${CFLAGS} ${T}.c ${LDFLAGS}
gdb --args ./${T}
vctest::
gcc -o t ${CFLAGS} t.c ${LDFLAGS} -lm
${VG} ./t
../ncdump/ncdump ./t.nc |tee t.dmp