Пример #1
0
inline void delete_attribute(h5xxObject const& object, std::string const& name)
{
    if (exists_attribute(object, name)) {
        if (H5Adelete(object.hid(), name.c_str()) < 0) {
            throw error("deleting attribute \"" + name + "\" from HDF5 object \"" + get_name(object) + "\"");
        }
    }
}
Пример #2
0
/*
 * Class:     hdf_hdf5lib_H5
 * Method:    H5Adelete
 * Signature: (JLjava/lang/String;)I
 */
JNIEXPORT jint JNICALL
Java_hdf_hdf5lib_H5_H5Adelete
    (JNIEnv *env, jclass clss, jlong loc_id, jstring name)
{
    herr_t      status = -1;
    const char *aName;

    PIN_JAVA_STRING(name, aName);
    if (aName != NULL) {
        status = H5Adelete((hid_t)loc_id, aName);

        UNPIN_JAVA_STRING(name, aName);

        if (status < 0)
            h5libraryError(env);
    }

    return (jint)status;
} /* end Java_hdf_hdf5lib_H5_H5Adelete */
Пример #3
0
/*----------------------------------------------------------------------------
 * Name:        h5adelete_c
 * Purpose:     Call H5Adelete to delete an attribute
 * Inputs:      obj_id - object identifier
 *              name - name of the attribute
 *              namelen - name length
 * Returns:     0 on success, -1 on failure
 * Programmer:  Elena Pourmal
 *              Thursday, August 12, 1999
 * Modifications:
 *---------------------------------------------------------------------------*/
int_f
nh5adelete_c (hid_t_f *obj_id, _fcd name, size_t_f *namelen)
{
    char *c_name=NULL;          /* Buffer to hold C string */
    int_f ret_value=0;          /* Return value */

     /*
      * Convert FORTRAN name to C name
      */
     if ((c_name = HD5f2cstring(name, (size_t)*namelen)) == NULL)
        HGOTO_DONE(FAIL);

     /*
      * Call H5Adelete function.
      */
     if (H5Adelete((hid_t)*obj_id, c_name) < 0)
         HGOTO_DONE(FAIL);

done:
    if(c_name) HDfree(c_name);
    return ret_value;
}
Пример #4
0
//--------------------------------------------------------------------------
// Function:	H5Object::removeAttr
///\brief	Removes the named attribute from this object.
///\param	name - IN: Name of the attribute to be removed
///\exception	H5::AttributeIException
// Programmer	Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
void H5Object::removeAttr( const char* name ) const
{
   herr_t ret_value = H5Adelete(getId(), name);
   if( ret_value < 0 )
      throw AttributeIException(inMemFunc("removeAttr"), "H5Adelete failed");
}
Пример #5
0
void LocID::removeAttr(const std::string &name) const {
    HErr res = H5Adelete(hid, name.c_str());
    res.check("LocID::removeAttr(): could not delete attribute");
}
Пример #6
0
char HBase::discardNamedAttr(const char * path)
{
    if(H5Adelete(fObjectId, path) < 0) return 0;
    return 1;
}
Пример #7
0
herr_t H5IMunlink_palette( hid_t loc_id,
                          const char *image_name,
                          const char *pal_name )
{
    hid_t       did;
    hid_t       atid;
    hid_t       aid;
    H5T_class_t aclass;
    int         ok_pal, has_pal;

    /* check the arguments */
    if(image_name == NULL) 
      return -1;
    if(pal_name == NULL) 
      return -1;

    /* Try to find the palette dataset */
    has_pal = H5LTfind_dataset( loc_id, pal_name );

    /* It does not exist. Return */
    if ( has_pal == 0 )
        return -1;

    /* The image dataset may or not have the attribute "PALETTE"
    * First we try to open to see if it is already there; if not, it is created.
    * If it exists, the array of references is extended to hold the reference
    * to the new palette
    */

    /* First we get the image id */
    if((did = H5Dopen2(loc_id, image_name, H5P_DEFAULT)) < 0)
        return -1;

    /* Try to find the attribute "PALETTE" on the >>image<< dataset */
    ok_pal = H5LT_find_attribute(did, "PALETTE");

    /* It does not exist. Nothing to do */
    if(ok_pal == 0)
        return -1;

    /* The attribute exists, open it */
    else if(ok_pal ==  1)
    {
        if((aid = H5Aopen(did, "PALETTE", H5P_DEFAULT)) < 0)
            goto out;

        if((atid = H5Aget_type(aid)) < 0)
            goto out;

        if((aclass = H5Tget_class(atid)) < 0)
            goto out;

        /* Check if it is really a reference */
        if(aclass == H5T_REFERENCE)
        {
            /* Delete the attribute */
            if(H5Adelete(did, "PALETTE") < 0)
                goto out;

        }  /* H5T_REFERENCE */

        if(H5Tclose(atid) < 0)
            goto out;

        /* Close the attribute. */
        if(H5Aclose(aid) < 0)
            goto out;

    } /* ok_pal */

    /* Close the image dataset. */
    if(H5Dclose(did) < 0)
        return -1;

    return 0;

out:
    H5Dclose( did );
    return -1;
}
Пример #8
0
herr_t H5IMlink_palette( hid_t loc_id,
                        const char *image_name,
                        const char *pal_name )

{
    hid_t       did;
    hid_t       atid=-1;
    hid_t       aid=-1;
    hid_t       asid=-1;
    hobj_ref_t  ref;         /* write a new reference */
    hobj_ref_t  *refbuf;     /* buffer to read references */
    hssize_t    n_refs;
    hsize_t     dim_ref;
    int         ok_pal;

    
    /* check the arguments */
    if (image_name == NULL) 
      return -1;
    if (pal_name == NULL) 
      return -1;

    /* The image dataset may or may not have the attribute "PALETTE"
    * First we try to open to see if it is already there; if not, it is created.
    * If it exists, the array of references is extended to hold the reference
    * to the new palette
    */

    /* First we get the image id */
    if((did = H5Dopen2(loc_id, image_name, H5P_DEFAULT)) < 0)
        return -1;

    /* Try to find the attribute "PALETTE" on the >>image<< dataset */
    ok_pal = H5LT_find_attribute( did, "PALETTE" );

    /*-------------------------------------------------------------------------
    * It does not exist. We create the attribute and one reference
    *-------------------------------------------------------------------------
    */
    if(ok_pal == 0 )
    {
        if((asid = H5Screate(H5S_SCALAR)) < 0)
            goto out;

        /* Create the attribute type for the reference */
        if((atid = H5Tcopy(H5T_STD_REF_OBJ)) < 0)
            goto out;

        /* Create the attribute "PALETTE" to be attached to the image*/
        if((aid = H5Acreate2(did, "PALETTE", atid, asid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
            goto out;

        /* Create a reference. The reference is created on the local id.  */
        if(H5Rcreate(&ref, loc_id, pal_name, H5R_OBJECT, (hid_t)-1) < 0)
            goto out;

        /* Write the attribute with the reference */
        if(H5Awrite(aid, atid, &ref) < 0)
            goto out;

        /* close */
        if(H5Sclose(asid) < 0)
            goto out;
        if(H5Tclose(atid) < 0)
            goto out;
        if(H5Aclose(aid) < 0)
            goto out;

    }

    /*-------------------------------------------------------------------------
    * The attribute already exists, open it
    *-------------------------------------------------------------------------
    */
    else if(ok_pal ==  1)
    {
        if((aid = H5Aopen(did, "PALETTE", H5P_DEFAULT)) < 0)
            goto out;

        if((atid = H5Aget_type(aid)) < 0)
            goto out;

        if(H5Tget_class(atid) < 0)
            goto out;

        /* Get and save the old reference(s) */
        if((asid = H5Aget_space(aid)) < 0)
            goto out;

        n_refs = H5Sget_simple_extent_npoints(asid);

        dim_ref = (hsize_t)n_refs + 1;

        refbuf = (hobj_ref_t*)HDmalloc( sizeof(hobj_ref_t) * (size_t)dim_ref );

        if ( H5Aread( aid, atid, refbuf ) < 0)
            goto out;

        /* The attribute must be deleted, in order to the new one can reflect the changes*/
        if(H5Adelete(did, "PALETTE") < 0)
            goto out;

        /* Create a new reference for this palette. */
        if ( H5Rcreate( &ref, loc_id, pal_name, H5R_OBJECT, (hid_t)-1 ) < 0)
            goto out;

        refbuf[n_refs] = ref;

        /* Create the data space for the new references */
        if(H5Sclose(asid) < 0)
            goto out;

        if((asid = H5Screate_simple(1, &dim_ref, NULL)) < 0)
            goto out;

        /* Create the attribute again with the changes of space */
        if(H5Aclose(aid) < 0)
            goto out;

        if((aid = H5Acreate2(did, "PALETTE", atid, asid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
            goto out;

        /* Write the attribute with the new references */
        if(H5Awrite(aid, atid, refbuf) < 0)
            goto out;

        /* close */
        if(H5Sclose(asid) < 0)
            goto out;
        if(H5Tclose(atid) < 0)
            goto out;
        if(H5Aclose(aid) < 0)
            goto out;

        HDfree( refbuf );

    } /* ok_pal ==  1 */

    /* Close the image dataset. */
    if ( H5Dclose( did ) < 0)
        return -1;

    return 0;

out:
    H5Dclose( did );
    H5Sclose( asid );
    H5Tclose( atid );
    H5Aclose( aid );
    return -1;
}
Пример #9
0
med_err _MEDattributeStringWr(med_idt pid,
			      const char * const attname,
			      const med_size attsize,
			      const char * const val)
{
  med_access_mode MED_ACCESS_MODE;
  med_idt _attid=0,aid=0;
  med_err _ret=-1;
  int     type_hdf=0;
  med_bool        _attmustbecreated= MED_FALSE;
  hsize_t         _attsize=0;
  med_size        _valsize=0;

  if ( (MED_ACCESS_MODE = _MEDmodeAcces(pid) ) == MED_ACC_UNDEF ) {
    MED_ERR_(_ret,MED_ERR_INVALID,MED_ERR_ACCESSMODE, "MED_ACC_UNDEF" );
    SSCRUTE(attname); goto ERROR;
  }

  _valsize=strlen(val);
  if (_valsize > attsize) {
    MED_ERR_(_ret,MED_ERR_INVALID,MED_ERR_ATTRIBUTE, attname );
    ISCRUTE_size(_valsize);ISCRUTE_size(attsize);goto ERROR;
  }

  if ((aid = H5Screate(H5S_SCALAR)) < 0){
    MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_DATASPACE, attname );
    ISCRUTE_id(aid);
  }

  if ( (type_hdf = H5Tcopy(H5T_C_S1)) < 0) {
    MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_HDFTYPE, MED_ERR_NAME_MSG );
    SSCRUTE("H5T_C_S1"); goto ERROR;
  }

  if ( H5Tset_size(type_hdf,_valsize+1) < 0) {
    MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_HDFTYPE, MED_ERR_NAME_MSG );
    SSCRUTE("H5T_C_S1"); goto ERROR;
  }

  if  ( (_attid=H5Aopen( pid, attname,H5P_DEFAULT ))  >= 0 )
    if ( MED_ACCESS_MODE == MED_ACC_RDEXT )  {
      MED_ERR_(_ret,MED_ERR_INVALID,MED_ERR_ACCESSMODE, "MED_ACC_RDEXT" );
      SSCRUTE(attname); goto ERROR;
    }

  if ( _attid > 0 ) {
    if ( (_attsize=H5Aget_storage_size(_attid) ) < 0 ) goto ERROR;
    if ( (_valsize+1)  > _attsize ) {
      if (H5Aclose(_attid) < 0) {
	MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_ATTRIBUTE,"");
	ISCRUTE_id(_attid);
	goto ERROR;
      }
      if ( H5Adelete(pid,attname) < 0 ) goto ERROR;
      _attmustbecreated=MED_TRUE;
    }
  }

  if ( (_attid < 0) || _attmustbecreated )
    if ( (_attid=H5Acreate( pid, attname, type_hdf, aid,  H5P_DEFAULT )) < 0 ) {
      MED_ERR_(_ret,MED_ERR_CREATE,MED_ERR_ATTRIBUTE, attname );
      goto ERROR;
    }

  if ( H5Awrite(_attid,type_hdf,val) < 0) {
    MED_ERR_(_ret,MED_ERR_WRITE,MED_ERR_ATTRIBUTE, attname );
    goto ERROR;
  }

  _ret=0;

 ERROR:

  if (type_hdf > 0 ) if ( H5Tclose(type_hdf) < 0) {
    MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_HDFTYPE, MED_ERR_ID_MSG );
    ISCRUTE_int(type_hdf);
  }

  if (aid > 0 ) if ( H5Sclose(aid) < 0) {
    MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_DATASPACE, MED_ERR_ID_MSG );
    ISCRUTE_id(aid);
  }

  if (_attid >0) if ( H5Aclose(_attid) < 0) {
    MED_ERR_(_ret,MED_ERR_CLOSE,MED_ERR_ATTRIBUTE, MED_ERR_ID_MSG );
    ISCRUTE_id(_attid);
  }


  return _ret;
}
Пример #10
0
/**
 * @internal I think all atts should be named the exact same thing, to
 * avoid confusion!
 *
 * @param ncid File and group ID.
 * @param varid Variable ID.
 * @param name Name of attribute.
 * @param newname New name for attribute.
 *
 * @return ::NC_NOERR No error.
 * @return ::NC_EBADID Bad ncid.
 * @return ::NC_EMAXNAME New name too long.
 * @return ::NC_EPERM File is read-only.
 * @return ::NC_ENAMEINUSE New name already in use.
 * @return ::NC_ENOTINDEFINE Classic model file not in define mode.
 * @return ::NC_EHDFERR HDF error.
 * @return ::NC_ENOMEM Out of memory.
 * @return ::NC_EINTERNAL Could not rebuild list.
 * @author Ed Hartnett
 */
int
NC4_rename_att(int ncid, int varid, const char *name, const char *newname)
{
   NC *nc;
   NC_GRP_INFO_T *grp;
   NC_FILE_INFO_T *h5;
   NC_VAR_INFO_T *var = NULL;
   NC_ATT_INFO_T *att;
   NCindex *list;
   char norm_newname[NC_MAX_NAME + 1], norm_name[NC_MAX_NAME + 1];
   hid_t datasetid = 0;
   int retval = NC_NOERR;

   if (!name || !newname)
      return NC_EINVAL;

   LOG((2, "nc_rename_att: ncid 0x%x varid %d name %s newname %s",
        ncid, varid, name, newname));

   /* If the new name is too long, that's an error. */
   if (strlen(newname) > NC_MAX_NAME)
      return NC_EMAXNAME;

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

   /* If the file is read-only, return an error. */
   if (h5->no_write)
      return NC_EPERM;

   /* Check and normalize the name. */
   if ((retval = nc4_check_name(newname, norm_newname)))
      return retval;

   /* Get the list of attributes. */
   if ((retval = getattlist(grp, varid, &var, &list)))
      return retval;

   /* Is new name in use? */
   att = (NC_ATT_INFO_T*)ncindexlookup(list,norm_newname);
   if(att != NULL)
      return NC_ENAMEINUSE;

   /* Normalize name and find the attribute. */
   if ((retval = nc4_normalize_name(name, norm_name)))
      return retval;

   att = (NC_ATT_INFO_T*)ncindexlookup(list,norm_name);
   if (!att)
      return NC_ENOTATT;

   /* If we're not in define mode, new name must be of equal or
      less size, if complying with strict NC3 rules. */
   if (!(h5->flags & NC_INDEF) && strlen(norm_newname) > strlen(att->hdr.name) &&
       (h5->cmode & NC_CLASSIC_MODEL))
      return NC_ENOTINDEFINE;

   /* Delete the original attribute, if it exists in the HDF5 file. */
   if (att->created)
   {
      if (varid == NC_GLOBAL)
      {
         if (H5Adelete(((NC_HDF5_GRP_INFO_T *)(grp->format_grp_info))->hdf_grpid,
                       att->hdr.name) < 0)
            return NC_EHDFERR;
      }
      else
      {
         if ((retval = nc4_open_var_grp2(grp, varid, &datasetid)))
            return retval;
         if (H5Adelete(datasetid, att->hdr.name) < 0)
            return NC_EHDFERR;
      }
      att->created = NC_FALSE;
   }

   /* Copy the new name into our metadata. */
   if(att->hdr.name) free(att->hdr.name);
   if (!(att->hdr.name = strdup(norm_newname)))
      return NC_ENOMEM;
   att->hdr.hashkey = NC_hashmapkey(att->hdr.name,strlen(att->hdr.name)); /* Fix hash key */

   att->dirty = NC_TRUE;

   /* Rehash the attribute list so that the new name is used */
   if(!ncindexrebuild(list))
      return NC_EINTERNAL;

   /* Mark attributes on variable dirty, so they get written */
   if(var)
      var->attr_dirty = NC_TRUE;

   return retval;
}
Пример #11
0
/**
 * @internal Delete an att. Rub it out. Push the button on
 * it. Liquidate it. Bump it off. Take it for a one-way
 * ride. Terminate it.
 *
 * @param ncid File and group ID.
 * @param varid Variable ID.
 * @param name Name of attribute to delete.
 *
 * @return ::NC_NOERR No error.
 * @return ::NC_EBADID Bad ncid.
 * @return ::NC_ENOTATT Attribute not found.
 * @return ::NC_EINVAL No name provided.
 * @return ::NC_EPERM File is read only.
 * @return ::NC_ENOTINDEFINE Classic model not in define mode.
 * @return ::NC_EINTERNAL Could not rebuild list.
 * @author Ed Hartnett, Dennis Heimbigner
 */
int
NC4_del_att(int ncid, int varid, const char *name)
{
   NC_GRP_INFO_T *grp;
   NC_VAR_INFO_T *var;
   NC_FILE_INFO_T *h5;
   NC_ATT_INFO_T *att;
   NCindex* attlist = NULL;
   hid_t locid = 0;
   int i;
   size_t deletedid;
   int retval;

   /* Name must be provided. */
   if (!name)
      return NC_EINVAL;

   LOG((2, "nc_del_att: ncid 0x%x varid %d name %s", ncid, varid, name));

   /* Find info for this file, group, and h5 info. */
   if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
      return retval;
   assert(h5 && grp);

   /* If the file is read-only, return an error. */
   if (h5->no_write)
      return NC_EPERM;

   /* If file is not in define mode, return error for classic model
    * files, otherwise switch to define mode. */
   if (!(h5->flags & NC_INDEF))
   {
      if (h5->cmode & NC_CLASSIC_MODEL)
         return NC_ENOTINDEFINE;
      if ((retval = NC4_redef(ncid)))
         return retval;
   }

   /* Get either the global or a variable attribute list. */
   if ((retval = getattlist(grp, varid, &var, &attlist)))
      return retval;

   /* Determine the location id in the HDF5 file. */
   if (varid == NC_GLOBAL)
      locid = ((NC_HDF5_GRP_INFO_T *)(grp->format_grp_info))->hdf_grpid;
   else if (var->created)
      locid = var->hdf_datasetid;

   /* Now find the attribute by name. */
   if (!(att = (NC_ATT_INFO_T*)ncindexlookup(attlist, name)))
      return NC_ENOTATT;

   /* Delete it from the HDF5 file, if it's been created. */
   if (att->created)
   {
      assert(locid);
      if (H5Adelete(locid, att->hdr.name) < 0)
         return NC_EATTMETA;
   }

   deletedid = att->hdr.id;

   /* Remove this attribute in this list */
   if ((retval = nc4_att_list_del(attlist, att)))
      return retval;

   /* Renumber all attributes with higher indices. */
   for (i = 0; i < ncindexsize(attlist); i++)
   {
      NC_ATT_INFO_T *a;
      if (!(a = (NC_ATT_INFO_T *)ncindexith(attlist, i)))
         continue;
      if (a->hdr.id > deletedid)
         a->hdr.id--;
   }

   /* Rebuild the index. */
   if (!ncindexrebuild(attlist))
      return NC_EINTERNAL;

   return NC_NOERR;
}
Пример #12
0
/* Delete an att. Rub it out. Push the button on it. Liquidate
   it. Bump it off. Take it for a one-way ride. Terminate it. Drop the
   bomb on it. You get the idea.
   Ed Hartnett, 10/1/3
*/
int
NC4_del_att(int ncid, int varid, const char *name)
{
   NC *nc;
   NC_GRP_INFO_T *grp;
   NC_HDF5_FILE_INFO_T *h5;
   NC_ATT_INFO_T *att, *natt;
   NC_VAR_INFO_T *var;
   NC_ATT_INFO_T **attlist = NULL;
   hid_t locid = 0, datasetid = 0;
   int retval = NC_NOERR;

   if (!name)
      return NC_EINVAL;

   LOG((2, "nc_del_att: ncid 0x%x varid %d name %s",
	ncid, varid, name));

   /* Find metadata for this file. */
   if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
      return retval;

   assert(h5 && grp);

   /* If the file is read-only, return an error. */
   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_del_att(nc->int_ncid, varid, name);
#endif /* USE_PNETCDF */

   /* If it's not in define mode, forget it. */
   if (!(h5->flags & NC_INDEF))
   {
      if (h5->cmode & NC_CLASSIC_MODEL)
	 return NC_ENOTINDEFINE;
      if ((retval = NC4_redef(ncid)))
	 BAIL(retval);
   }

   /* Get either the global or a variable attribute list. Also figure
      out the HDF5 location it's attached to. */
   if (varid == NC_GLOBAL)
   {
      attlist = &grp->att;
      locid = grp->hdf_grpid;
   }
   else
   {
      for(var = grp->var; var; var = var->l.next)
      {
	 if (var->varid == varid)
	 {
	    attlist = &var->att;
	    break;
	 }
      }
      if (!var)
	 return NC_ENOTVAR;
      if (var->created)
	 locid = var->hdf_datasetid;
   }

   /* Now find the attribute by name or number. */
   for (att = *attlist; att; att = att->l.next)
      if (!strcmp(att->name, name))
	 break;

   /* If att is NULL, we couldn't find the attribute. */
   if (!att)
      BAIL_QUIET(NC_ENOTATT);

   /* Delete it from the HDF5 file, if it's been created. */
   if (att->created)
   {
      assert(locid);

      if(H5Adelete(locid, att->name) < 0)
	 BAIL(NC_EATTMETA);
   }

   /* Renumber all following attributes. */
   for (natt = att->l.next; natt; natt = natt->l.next)
      natt->attnum--;

   /* Delete this attribute from this list. */
   if ((retval = nc4_att_list_del(attlist, att)))
      BAIL(retval);

 exit:
   if (datasetid > 0) H5Dclose(datasetid);
   return retval;
}
Пример #13
0
/* I think all atts should be named the exact same thing, to avoid
   confusion! */
int
NC4_rename_att(int ncid, int varid, const char *name,
	      const char *newname)
{
   NC *nc;
   NC_GRP_INFO_T *grp;
   NC_HDF5_FILE_INFO_T *h5;
   NC_VAR_INFO_T *var;
   NC_ATT_INFO_T *att, *list;
   char norm_newname[NC_MAX_NAME + 1], norm_name[NC_MAX_NAME + 1];
   hid_t datasetid = 0;
   int retval = NC_NOERR;

   if (!name || !newname)
      return NC_EINVAL;

   LOG((2, "nc_rename_att: ncid 0x%x varid %d name %s newname %s",
	ncid, varid, name, newname));

   /* If the new name is too long, that's an error. */
   if (strlen(newname) > NC_MAX_NAME)
      return NC_EMAXNAME;

   /* Find metadata for this file. */
   if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
      return retval;

   assert(h5 && grp);

   /* If the file is read-only, return an error. */
   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_att(nc->int_ncid, varid, name, newname);
#endif /* USE_PNETCDF */

   /* Check and normalize the name. */
   if ((retval = nc4_check_name(newname, norm_newname)))
      return retval;

   /* Is norm_newname in use? */
   if (varid == NC_GLOBAL)
   {
      list = grp->att;
   }
   else
   {
      for (var = grp->var; var; var = var->l.next)
	 if (var->varid == varid)
	 {
	    list = var->att;
	    break;
	 }
      if (!var)
	 return NC_ENOTVAR;
   }
   for (att = list; att; att = att->l.next)
      if (!strncmp(att->name, norm_newname, NC_MAX_NAME))
	 return NC_ENAMEINUSE;

   /* Normalize name and find the attribute. */
   if ((retval = nc4_normalize_name(name, norm_name)))
      return retval;
   for (att = list; att; att = att->l.next)
      if (!strncmp(att->name, norm_name, NC_MAX_NAME))
	 break;
   if (!att)
      return NC_ENOTATT;

   /* If we're not in define mode, new name must be of equal or
      less size, if complying with strict NC3 rules. */
   if (!(h5->flags & NC_INDEF) && strlen(norm_newname) > strlen(att->name) &&
       (h5->cmode & NC_CLASSIC_MODEL))
      return NC_ENOTINDEFINE;

   /* Delete the original attribute, if it exists in the HDF5 file. */
   if (att->created)
   {
      if (varid == NC_GLOBAL)
      {
         if (H5Adelete(grp->hdf_grpid, att->name) < 0)
	    return NC_EHDFERR;
      }
      else
      {
	 if ((retval = nc4_open_var_grp2(grp, varid, &datasetid)))
	    return retval;
         if (H5Adelete(datasetid, att->name) < 0)
	    return NC_EHDFERR;
      }
      att->created = NC_FALSE;
   }

   /* Copy the new name into our metadata. */
   free(att->name);
   if (!(att->name = malloc((strlen(norm_newname) + 1) * sizeof(char))))
      return NC_ENOMEM;
   strcpy(att->name, norm_newname);
   att->dirty = NC_TRUE;

   return retval;
}