mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-01-18 15:55:12 +08:00
moving lazy atts code to libhdf5
This commit is contained in:
parent
1df4bb1762
commit
8e7fc913cb
@ -279,43 +279,35 @@ exit:
|
||||
* @param ncid File and group ID.
|
||||
* @param varid Variable ID.
|
||||
* @param name Name of attribute.
|
||||
* @param xtype Pointer that gets (file) type of attribute.
|
||||
* @param xtype Pointer that gets (file) type of attribute. Ignored if
|
||||
* NULL.
|
||||
* @param mem_type The type of attribute data in memory.
|
||||
* @param lenp Pointer that gets length of attribute array.
|
||||
* @param attnum Pointer that gets the index number of this attribute.
|
||||
* @param data Pointer that gets attribute data.
|
||||
* @param lenp Pointer that gets length of attribute array. Ignored if
|
||||
* NULL.
|
||||
* @param attnum Pointer that gets the index number of this
|
||||
* attribute. Ignored if NULL.
|
||||
* @param data Pointer that gets attribute data. Ignored if NULL.
|
||||
*
|
||||
* @return ::NC_NOERR No error.
|
||||
* @return ::NC_EBADID Bad ncid.
|
||||
* @author Ed Hartnett
|
||||
*/
|
||||
static int
|
||||
int
|
||||
nc4_get_att(int ncid, int varid, const char *name, nc_type *xtype,
|
||||
nc_type mem_type, size_t *lenp, int *attnum, void *data)
|
||||
{
|
||||
NC *nc;
|
||||
NC_GRP_INFO_T *grp;
|
||||
NC_FILE_INFO_T *h5;
|
||||
NC_ATT_INFO_T *att = NULL;
|
||||
NC_VAR_INFO_T *var;
|
||||
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;
|
||||
NC_GRP_INFO_T *grp;
|
||||
NC_VAR_INFO_T *var = NULL;
|
||||
int retval;
|
||||
|
||||
if (attnum)
|
||||
my_attnum = *attnum;
|
||||
|
||||
LOG((3, "%s: ncid 0x%x varid %d name %s attnum %d mem_type %d",
|
||||
__func__, ncid, varid, name, my_attnum, mem_type));
|
||||
LOG((3, "%s: ncid 0x%x varid %d mem_type %d", __func__, ncid,
|
||||
varid, mem_type));
|
||||
|
||||
/* Find info for this file, group, and h5 info. */
|
||||
if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5)))
|
||||
if ((retval = nc4_find_grp_h5(ncid, &grp, &h5)))
|
||||
return retval;
|
||||
assert(h5 && grp);
|
||||
|
||||
/* Check varid */
|
||||
if (varid != NC_GLOBAL)
|
||||
@ -325,152 +317,12 @@ nc4_get_att(int ncid, int varid, const char *name, nc_type *xtype,
|
||||
assert(var->hdr.id == varid);
|
||||
}
|
||||
|
||||
if (name == NULL)
|
||||
BAIL(NC_EBADNAME);
|
||||
/* Name is required. */
|
||||
if (!name)
|
||||
return NC_EBADNAME;
|
||||
|
||||
/* Normalize name. */
|
||||
if ((retval = nc4_normalize_name(name, norm_name)))
|
||||
BAIL(retval);
|
||||
|
||||
/* Read the atts for this group/var, if they have not been read. */
|
||||
if (varid == NC_GLOBAL)
|
||||
{
|
||||
if (grp->atts_not_read)
|
||||
if ((retval = nc4_read_atts(grp, NULL)))
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (var->atts_not_read)
|
||||
if ((retval = nc4_read_atts(grp, var)))
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* If this is one of the reserved atts, use nc_get_att_special. */
|
||||
if (nc->ext_ncid == ncid && varid == NC_GLOBAL) {
|
||||
const NC_reservedatt* ra = NC_findreserved(norm_name);
|
||||
if(ra != NULL && (ra->flags & NAMEONLYFLAG))
|
||||
return nc4_get_att_special(h5, norm_name, xtype, mem_type, lenp, attnum, data);
|
||||
}
|
||||
|
||||
/* Find the attribute, if it exists. */
|
||||
if ((retval = nc4_find_grp_att(grp, varid, norm_name, my_attnum, &att)))
|
||||
return 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)
|
||||
if ((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->hdr.id;
|
||||
}
|
||||
|
||||
/* 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, &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))))
|
||||
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, &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
|
||||
{
|
||||
memcpy(data, bufr, (size_t)(att->len * type_size));
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
if (need_to_convert)
|
||||
free(bufr);
|
||||
if (range_error)
|
||||
retval = NC_ERANGE;
|
||||
return retval;
|
||||
return nc4_get_att_ptrs(h5, grp, var, name, xtype, mem_type, lenp,
|
||||
attnum, data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user