示例#1
0
/* Given an ncid and group name (NULL gets root group), return
 * the ncid of that group. */
int
NC4_inq_ncid(int ncid, const char *name, int *grp_ncid)
{
   NC_GRP_INFO_T *grp, *g;
   NC_HDF5_FILE_INFO_T *h5;
   char norm_name[NC_MAX_NAME + 1];
   int retval;

   LOG((2, "nc_inq_ncid: ncid 0x%x name %s", ncid, name));
   
   /* Find info for this file and group, and set pointer to each. */
   if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
      return retval;

   /* Groups only work with netCDF-4/HDF5 files... */
   if (!h5)
      return NC_ENOTNC4;

   /* Normalize name. */
   if ((retval = nc4_normalize_name(name, norm_name)))
      return retval;

   /* Look through groups for one of this name. */
   for (g = grp->children; g; g = g->next)
      if (!strcmp(norm_name, g->name)) /* found it! */
      {
	 if (grp_ncid)
	    *grp_ncid = grp->nc4_info->controller->ext_ncid | g->nc_grpid;
	 return NC_NOERR;
      }
   
   /* If we got here, we didn't find the named group. */
   return NC_ENOGRP;
}
示例#2
0
/* Given parent ncid and name, find ncid. (Root group is named "/".) */
int
nc_inq_grp_ncid(int ncid, const char *grp_name, int *parent_ncid)
{
   NC_GRP_INFO_T *grp, *g1;
   NC_HDF5_FILE_INFO_T *h5;
   char norm_name[NC_MAX_NAME + 1];
   int pncid;
   int retval;

   LOG((2, "nc_inq_grp_parent: ncid 0x%x", ncid));

   if (!grp_name)
      return NC_EINVAL;

   if (strlen(grp_name) > NC_MAX_NAME)
      return NC_EINVAL;

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

   /* Groups only work with netCDF-4/HDF5 files... */
   if (!h5)
      return NC_ENOTNC4;

   /* Normalize name. */
   if ((retval = nc4_normalize_name(grp_name, norm_name)))
      return retval;

   /* Find group with this name, if any. */
   for (g1 = grp->children; g1; g1 = g1->next)
      if (!strcmp(g1->name, norm_name))
      {
	 pncid = grp->file->ext_ncid | g1->nc_grpid; 
	 break;
      }

   /* Didn't find it? */
   if (!g1)
      return NC_ENOGRP;

   if (parent_ncid)
      *parent_ncid = pncid;

   return NC_NOERR;
}
示例#3
0
/**
 * @internal Given the typeid and the name, get the fieldid.
 *
 * @param ncid File and group ID.
 * @param typeid1 Type ID.
 * @param name Name of field.
 * @param fieldidp Pointer that gets new field ID.
 *
 * @return ::NC_NOERR No error.
 * @return ::NC_EBADID Bad ncid.
 * @return ::NC_EBADTYPE Type not found.
 * @return ::NC_EBADFIELD Field not found.
 * @author Ed Hartnett
 */
int
NC4_inq_compound_fieldindex(int ncid, nc_type typeid1, const char *name, int *fieldidp)
{
    NC_FILE_INFO_T *h5;
    NC_TYPE_INFO_T *type;
    NC_FIELD_INFO_T *field;
    char norm_name[NC_MAX_NAME + 1];
    int retval;
    int i;

    LOG((2, "nc_inq_compound_fieldindex: ncid 0x%x typeid %d name %s",
         ncid, typeid1, name));

    /* Find file metadata. */
    if ((retval = nc4_find_grp_h5(ncid, NULL, &h5)))
        return retval;

    /* Find the type. */
    if ((retval = nc4_find_type(h5, typeid1, &type)))
        return retval;

    /* Did the user give us a good compound type typeid? */
    if (!type || type->nc_type_class != NC_COMPOUND)
        return NC_EBADTYPE;

    /* Normalize name. */
    if ((retval = nc4_normalize_name(name, norm_name)))
        return retval;

    /* Find the field with this name. */
    for (i = 0; i < nclistlength(type->u.c.field); i++)
    {
        field = nclistget(type->u.c.field, i);
        assert(field);
        if (!strcmp(field->hdr.name, norm_name))
            break;
        field = NULL; /* because this is the indicator of not found */
    }

    if (!field)
        return NC_EBADFIELD;

    if (fieldidp)
        *fieldidp = field->hdr.id;
    return NC_NOERR;
}
示例#4
0
文件: nc4dim.c 项目: 151706061/VTK
/* Given dim name, find its id. */
int
NC4_inq_dimid(int ncid, const char *name, int *idp)
{
   NC_FILE_INFO_T *nc;
   NC_GRP_INFO_T *grp, *g;
   NC_HDF5_FILE_INFO_T *h5;
   NC_DIM_INFO_T *dim;
   char norm_name[NC_MAX_NAME + 1];
   int finished = 0;
   int retval;

   LOG((2, "nc_inq_dimid: ncid 0x%x name %s", ncid, name));

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

#ifdef USE_PNETCDF
   /* Take care of files created/opened with parallel-netcdf library. */
   if (nc->pnetcdf_file)
      return ncmpi_inq_dimid(nc->int_ncid, name, idp);
#endif /* USE_PNETCDF */

   /* Handle netcdf-3 files. */
   assert(h5);

   assert(nc && grp);

   /* Normalize name. */
   if ((retval = nc4_normalize_name(name, norm_name)))
      return retval;

   /* Go through each dim and check for a name match. */
   for (g = grp; g && !finished; g = g->parent)
      for (dim = g->dim; dim; dim = dim->next)
	 if (!strncmp(dim->name, norm_name, NC_MAX_NAME))
	 {
	    if (idp)
	       *idp = dim->dimid;
	    finished++;
	    return NC_NOERR;
	 }

   return NC_EBADDIM;
}
示例#5
0
文件: nc4dim.c 项目: dschwen/libmesh
/**
 * @internal Given dim name, find its id.
 *
 * @param ncid File and group ID.
 * @param name Name of the dimension to find.
 * @param idp Pointer that gets dimension ID.
 *
 * @return ::NC_NOERR No error.
 * @return ::NC_EBADID Bad ncid.
 * @return ::NC_EBADDIM Dimension not found.
 * @return ::NC_EINVAL Invalid input. Name must be provided.
 * @author Ed Hartnett
 */
int
NC4_inq_dimid(int ncid, const char *name, int *idp)
{
   NC *nc;
   NC_GRP_INFO_T *grp, *g;
   NC_FILE_INFO_T *h5;
   NC_DIM_INFO_T *dim;
   char norm_name[NC_MAX_NAME + 1];
   int retval;
   int found;

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

   /* Check input. */
   if (!name)
      return NC_EINVAL;

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

   /* Normalize name. */
   if ((retval = nc4_normalize_name(name, norm_name)))
      return retval;

   /* check for a name match in this group and its parents */
   found = 0;
   for (g = grp; g ; g = g->parent) {
      dim = (NC_DIM_INFO_T*)ncindexlookup(g->dim,norm_name);
      if(dim != NULL) {found = 1; break;}
   }
   if(!found)
      return NC_EBADDIM;
   assert(dim != NULL);
   if (idp)
      *idp = dim->hdr.id;
   return NC_NOERR;
}
示例#6
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;
}
示例#7
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;
}
示例#8
0
/* Get or put attribute metadata from our linked list of file
   info. Always locate the attribute by name, never by attnum.
   The mem_type is ignored if data=NULL. */
int
nc4_get_att(int ncid, NC *nc, int varid, const char *name,
	    nc_type *xtype, nc_type mem_type, size_t *lenp,
	    int *attnum, int is_long, void *data)
{
   NC_GRP_INFO_T *grp;
   NC_HDF5_FILE_INFO_T *h5;
   NC_ATT_INFO_T *att = NULL;
   int my_attnum = -1;

   int need_to_convert = 0;
   int range_error = NC_NOERR;
   void *bufr = NULL;
   size_t type_size;
   char norm_name[NC_MAX_NAME + 1];
   int i;
   int retval = NC_NOERR;

   if (attnum)
      my_attnum = *attnum;
   assert(nc && NC4_DATA(nc));

   LOG((3, "%s: ncid 0x%x varid %d name %s attnum %d mem_type %d",
	__func__, ncid, varid, name, my_attnum, mem_type));

   /* Find info for this file and group, and set pointer to each. */
   h5 = NC4_DATA(nc);
   if (!(grp = nc4_rec_find_grp(h5->root_grp, (ncid & GRP_ID_MASK))))
      BAIL(NC_EBADGRPID);

   /* Normalize name. */
   if ((retval = nc4_normalize_name(name, norm_name)))
      BAIL(retval);

   /* Find the attribute, if it exists. If we don't find it, we are
      major failures. */
   if ((retval = nc4_find_grp_att(grp, varid, norm_name, my_attnum, &att)))
      BAIL(retval);

   /* If mem_type is NC_NAT, it means we want to use the attribute's
    * file type as the mem type as well. */
   if (mem_type == NC_NAT)
      mem_type = att->nc_typeid;

   /* If the attribute is NC_CHAR, and the mem_type isn't, or vice
    * versa, that's a freakish attempt to convert text to
    * numbers. Some pervert out there is trying to pull a fast one!
    * Send him an NC_ECHAR error...*/
   if (data && att->len &&
       ((att->nc_typeid == NC_CHAR && mem_type != NC_CHAR) ||
	(att->nc_typeid != NC_CHAR && mem_type == NC_CHAR)))
      BAIL(NC_ECHAR); /* take that, you freak! */

   /* Copy the info. */
   if (lenp)
      *lenp = att->len;
   if (xtype)
      *xtype = att->nc_typeid;
   if (attnum)
      *attnum = att->attnum;

   /* Zero len attributes are easy to read! */
   if (!att->len)
      BAIL(NC_NOERR);

   /* Later on, we will need to know the size of this type. */
   if ((retval = nc4_get_typelen_mem(h5, mem_type, is_long, &type_size)))
      BAIL(retval);

   /* We may have to convert data. Treat NC_CHAR the same as
    * NC_UBYTE. If the mem_type is NAT, don't try any conversion - use
    * the attribute's type. */
   if (data && att->len && mem_type != att->nc_typeid &&
       mem_type != NC_NAT &&
       !(mem_type == NC_CHAR &&
	 (att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE)))
   {
      if (!(bufr = malloc((size_t)(att->len * type_size))))
	 BAIL(NC_ENOMEM);
      need_to_convert++;
      if ((retval = nc4_convert_type(att->data, bufr, att->nc_typeid,
				     mem_type, (size_t)att->len, &range_error,
				     NULL, (h5->cmode & NC_CLASSIC_MODEL), 0, is_long)))
	 BAIL(retval);

      /* For strict netcdf-3 rules, ignore erange errors between UBYTE
       * and BYTE types. */
      if ((h5->cmode & NC_CLASSIC_MODEL) &&
	  (att->nc_typeid == NC_UBYTE || att->nc_typeid == NC_BYTE) &&
	  (mem_type == NC_UBYTE || mem_type == NC_BYTE) &&
	  range_error)
	 range_error = 0;
   }
   else
   {
      bufr = att->data;
   }

   /* If the caller wants data, copy it for him. If he hasn't
      allocated enough memory for it, he will burn in segmentation
      fault hell, writhing with the agony of undiscovered memory
      bugs! */
   if (data)
   {
      if (att->vldata)
      {
	 size_t base_typelen;
	 hvl_t *vldest = data;
	 NC_TYPE_INFO_T *type;

         /* Get the type object for the attribute's type */
	 if ((retval = nc4_find_type(h5, att->nc_typeid, &type)))
	   BAIL(retval);

         /* Retrieve the size of the base type */
         if ((retval = nc4_get_typelen_mem(h5, type->u.v.base_nc_typeid, 0, &base_typelen)))
            BAIL(retval);

	 for (i = 0; i < att->len; i++)
	 {
	    vldest[i].len = att->vldata[i].len;
	    if (!(vldest[i].p = malloc(vldest[i].len * base_typelen)))
	       BAIL(NC_ENOMEM);
	    memcpy(vldest[i].p, att->vldata[i].p, vldest[i].len * base_typelen);
	 }
      }
      else if (att->stdata)
      {
	 for (i = 0; i < att->len; i++)
	 {
            /* Check for NULL pointer for string (valid in HDF5) */
            if(att->stdata[i])
            {
                if (!(((char **)data)[i] = strdup(att->stdata[i])))
                   BAIL(NC_ENOMEM);
            }
            else
                ((char **)data)[i] = att->stdata[i];
	 }
      }
      else
      {
	 /* For long types, we need to handle this special... */
	 if (is_long && att->nc_typeid == NC_INT)
	 {
	    long *lp = data;
	    int *ip = bufr;

	    for (i = 0; i < att->len; i++)
	       *lp++ = *ip++;
	 }
	 else
	    memcpy(data, bufr, (size_t)(att->len * type_size));
      }
   }

 exit:
   if (need_to_convert)
      free(bufr);
   if (range_error)
      retval = NC_ERANGE;
   return retval;
}