mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-02-17 16:50:18 +08:00
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:
parent
1c23ec06b8
commit
b85d3568ec
@ -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;
|
||||
|
@ -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*);
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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*/
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
|
@ -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)))
|
||||
|
@ -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,
|
||||
|
||||
|
13
ncgen/Make0
13
ncgen/Make0
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user