From 8e7fc913cba09fbff96f44bbf0609356641aabbd Mon Sep 17 00:00:00 2001 From: Ed Hartnett Date: Mon, 26 Nov 2018 08:24:18 -0700 Subject: [PATCH] moving lazy atts code to libhdf5 --- libsrc4/nc4attr.c | 186 +++++----------------------------------------- 1 file changed, 19 insertions(+), 167 deletions(-) diff --git a/libsrc4/nc4attr.c b/libsrc4/nc4attr.c index 7970b2387..e65281d02 100644 --- a/libsrc4/nc4attr.c +++ b/libsrc4/nc4attr.c @@ -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); } /**