예제 #1
0
파일: nc4dim.c 프로젝트: 151706061/VTK
/* Rename a dimension, for those who like to prevaricate. */
int
NC4_rename_dim(int ncid, int dimid, const char *name)
{
   NC_FILE_INFO_T *nc;
   NC_GRP_INFO_T *grp;
   NC_HDF5_FILE_INFO_T *h5;
   NC_DIM_INFO_T *dim;
   char norm_name[NC_MAX_NAME + 1];
   int retval;

   if (!name)
      return NC_EINVAL;

   LOG((2, "nc_rename_dim: ncid 0x%x dimid %d name %s", ncid, 
	dimid, name));

   /* Find info for this file and group, and set pointer to each. */
   if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))      
      return retval;
   assert(nc);
   
#ifdef USE_PNETCDF
   /* Take care of files created/opened with parallel-netcdf library. */
   if (nc->pnetcdf_file)
      return ncmpi_rename_dim(nc->int_ncid, dimid, name);
#endif /* USE_PNETCDF */

   /* Handle netcdf-3 cases. */
   assert(h5);
   assert(h5 && grp);

   /* Trying to write to a read-only file? No way, Jose! */
   if (h5->no_write)
      return NC_EPERM;

   /* Make sure this is a valid netcdf name. */
   if ((retval = nc4_check_name(name, norm_name)))
      return retval;

   /* Make sure the new name is not already in use in this group. */
   for (dim = grp->dim; dim; dim = dim->next)
      if (!strncmp(dim->name, norm_name, NC_MAX_NAME))
	 return NC_ENAMEINUSE;

   /* Find the dim. */
   for (dim = grp->dim; dim; dim = dim->next)
      if (dim->dimid == dimid)
	 break;
   if (!dim)
      return NC_EBADDIM;

   /* If not in define mode, switch to it, unless the new name is
    * shorter. (This is in accordance with the v3 interface.) */
/*    if (!(h5->flags & NC_INDEF) && strlen(name) > strlen(dim->name)) */
/*    { */
/*       if (h5->cmode & NC_CLASSIC_MODEL) */
/* 	 return NC_ENOTINDEFINE; */
/*       if ((retval = nc_redef(ncid))) */
/* 	 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 dim, 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 (!dim->old_name)
   {
      if (!(dim->old_name = malloc((strlen(dim->name) + 1) * sizeof(char))))
	 return NC_ENOMEM;
      strcpy(dim->old_name, dim->name);
   }

   /* Give the dimension its new name in metadata. UTF8 normalization
    * has been done. */
   free(dim->name);
   if (!(dim->name = malloc((strlen(norm_name) + 1) * sizeof(char))))
      return NC_ENOMEM;
   strcpy(dim->name, norm_name);

   return NC_NOERR;
}
예제 #2
0
파일: nc4dim.c 프로젝트: UV-CDAT/netcdf-c
/* Rename a dimension, for those who like to prevaricate. */
int
NC4_rename_dim(int ncid, int dimid, const char *name)
{
   NC *nc;
   NC_GRP_INFO_T *grp;
   NC_HDF5_FILE_INFO_T *h5;
   NC_DIM_INFO_T *dim, *tmp_dim;
   char norm_name[NC_MAX_NAME + 1];
   int retval;

   if (!name)
      return NC_EINVAL;

   LOG((2, "%s: ncid 0x%x dimid %d name %s", __func__, ncid, 
	dimid, name));

   /* Find info for this file and group, and set pointer to each. */
   if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))      
      return retval;

   assert(nc);
   assert(h5 && grp);
   
   /* Trying to write to a read-only file? No way, Jose! */
   if (h5->no_write)
      return NC_EPERM;

#if 0 /*def USE_PNETCDF*/
   /* Take care of files created/opened with parallel-netcdf library. */
   if (h5->pnetcdf_file)
      return ncmpi_rename_dim(nc->int_ncid, dimid, name);
#endif /* USE_PNETCDF */

   /* Make sure this is a valid netcdf name. */
   if ((retval = nc4_check_name(name, norm_name)))
      return retval;

   /* Check if name is in use, and retain a pointer to the correct dim */
   tmp_dim = NULL;
   for (dim = grp->dim; dim; dim = dim->l.next)
   {
      if (!strncmp(dim->name, norm_name, NC_MAX_NAME))
	 return NC_ENAMEINUSE;
      if (dim->dimid == dimid)
	 tmp_dim = dim;
   }
   if (!tmp_dim)
      return NC_EBADDIM;
   dim = tmp_dim;

   /* Check for renaming dimension w/o variable */
   if (dim->hdf_dimscaleid)
   {
      /* Sanity check */
      assert(!dim->coord_var);

      /* Close the HDF5 dataset */
      if (H5Dclose(dim->hdf_dimscaleid) < 0) 
         return NC_EHDFERR;
      dim->hdf_dimscaleid = 0;
            
      /* Now delete the dataset (it will be recreated later, if necessary) */
      if (H5Gunlink(grp->hdf_grpid, dim->name) < 0)
         return NC_EDIMMETA;
   }

   /* Give the dimension its new name in metadata. UTF8 normalization
    * has been done. */
   if(dim->name)
      free(dim->name);
   if (!(dim->name = malloc((strlen(norm_name) + 1) * sizeof(char))))
      return NC_ENOMEM;
   strcpy(dim->name, norm_name);

   /* Check if dimension was a coordinate variable, but names are different now */
   if (dim->coord_var && strcmp(dim->name, dim->coord_var->name))
   {
      /* Break up the coordinate variable */
      if ((retval = nc4_break_coord_var(grp, dim->coord_var, dim)))
         return retval;
   }

   /* Check if dimension should become a coordinate variable */
   if (!dim->coord_var)
   {
      NC_VAR_INFO_T *var;

      /* Attempt to find a variable with the same name as the dimension in
       * the current group. */
      if ((retval = nc4_find_var(grp, dim->name, &var)))
         return retval;

      /* Check if we found a variable and the variable has the dimension in
       * index 0. */
      if (var && var->dim[0] == dim)
      {
          /* Sanity check */
          assert(var->dimids[0] == dim->dimid);

          /* Reform the coordinate variable */
          if ((retval = nc4_reform_coord_var(grp, var, dim)))
             return retval;
      }
   }

   return NC_NOERR;
}