44/**
55 * @file
66 * @internal This file contains functions that are used in file
7- * opens, both fast and slow .
7+ * opens.
88 *
99 * @author Ed Hartnett
1010 */
@@ -228,6 +228,7 @@ get_type_info2(NC_FILE_INFO_T *h5, hid_t datasetid,
228228
229229 return NC_EBADTYPID ;
230230}
231+
231232/**
232233 * @internal This function reads the hacked in coordinates attribute I
233234 * use for multi-dimensional coordinates.
@@ -985,7 +986,8 @@ get_netcdf_type(NC_FILE_INFO_T *h5, hid_t native_typeid,
985986}
986987
987988/**
988- * @internal Read an attribute. This is called by att_read_var_callbk().
989+ * @internal Read an attribute. This is called by
990+ * att_read_callbk().
989991 *
990992 * @param grp Pointer to group info struct.
991993 * @param attid Attribute ID.
@@ -1185,83 +1187,6 @@ read_hdf5_att(NC_GRP_INFO_T *grp, hid_t attid, NC_ATT_INFO_T *att)
11851187 return retval ;
11861188}
11871189
1188- /**
1189- * @internal This function is called by nc4_rec_read_metadata to read
1190- * all the group level attributes (the NC_GLOBAL atts for this
1191- * group).
1192- *
1193- * @param grp Pointer to group info struct.
1194- *
1195- * @return ::NC_NOERR No error.
1196- * @return ::NC_EHDFERR HDF5 returned error.
1197- * @author Ed Hartnett
1198- */
1199- int
1200- nc4_read_grp_atts (NC_GRP_INFO_T * grp )
1201- {
1202- hid_t attid = -1 ;
1203- hsize_t num_obj , i ;
1204- NC_ATT_INFO_T * att ;
1205- NC_TYPE_INFO_T * type ;
1206- char obj_name [NC_MAX_HDF5_NAME + 1 ];
1207- int retval = NC_NOERR ;
1208- int hidden = 0 ;
1209-
1210- num_obj = H5Aget_num_attrs (grp -> hdf_grpid );
1211- for (i = 0 ; i < num_obj ; i ++ )
1212- {
1213- if ((attid = H5Aopen_idx (grp -> hdf_grpid , (unsigned int )i )) < 0 )
1214- BAIL (NC_EATTMETA );
1215- if (H5Aget_name (attid , NC_MAX_NAME + 1 , obj_name ) < 0 )
1216- BAIL (NC_EATTMETA );
1217- LOG ((3 , "reading attribute of _netCDF group, named %s" , obj_name ));
1218-
1219- /* See if this a hidden, global attribute */
1220- hidden = 0 ; /* default */
1221- if (grp -> nc4_info -> root_grp == grp ) {
1222- const NC_reservedatt * ra = NC_findreserved (obj_name );
1223- if (ra != NULL && (ra -> flags & NAMEONLYFLAG ))
1224- hidden = 1 ;
1225- }
1226-
1227- /* This may be an attribute telling us that strict netcdf-3
1228- * rules are in effect. If so, we will make note of the fact,
1229- * but not add this attribute to the metadata. It's not a user
1230- * attribute, but an internal netcdf-4 one. */
1231- if (strcmp (obj_name , NC3_STRICT_ATT_NAME )== 0 )
1232- grp -> nc4_info -> cmode |= NC_CLASSIC_MODEL ;
1233- else if (!hidden ) {
1234- /* Add an att struct at the end of the list, and then go to it. */
1235- if ((retval = nc4_att_list_add (grp -> att , obj_name , & att )))
1236- BAIL (retval );
1237- retval = read_hdf5_att (grp , attid , att );
1238- if (retval == NC_EBADTYPID ) {
1239- if ((retval = nc4_att_list_del (grp -> att , att )))
1240- BAIL (retval );
1241- } else if (retval ) {
1242- BAIL (retval );
1243- } else {
1244- att -> created = NC_TRUE ;
1245- if ((retval = nc4_find_type (grp -> nc4_info , att -> nc_typeid , & type )))
1246- BAIL (retval );
1247- }
1248- }
1249- /* Unconditionally close the open attribute */
1250- (void )H5Aclose (attid );
1251- attid = -1 ;
1252- }
1253-
1254- /* Remember that we have read the atts for this group. */
1255- grp -> atts_not_read = 0 ;
1256-
1257- exit :
1258- if (attid > 0 ) {
1259- if (H5Aclose (attid ) < 0 )
1260- BAIL2 (NC_EHDFERR );
1261- }
1262- return retval ;
1263- }
1264-
12651190/**
12661191 * @internal Wrap HDF5 allocated memory free operations
12671192 *
@@ -1587,41 +1512,57 @@ read_type(NC_GRP_INFO_T *grp, hid_t hdf_typeid, char *type_name)
15871512}
15881513
15891514/**
1590- * @internal Callback function for reading attributes. This is used by
1591- * read_var() .
1515+ * @internal Callback function for reading attributes. This is used
1516+ * for both global and variable attributes .
15921517 *
15931518 * @param loc_id HDF5 attribute ID.
15941519 * @param att_name Name of the attrigute.
15951520 * @param ainfo HDF5 info struct for attribute.
1596- * @param att_data The attribute data.
1521+ * @param att_data Pointer to an att_iter_info struct, which contains
1522+ * pointers to the NC_GRP_INFO_T and (for variable attributes) the
1523+ * NC_VAR_INFO_T. For global atts the var pointer is NULL.
15971524 *
1598- * @return ::NC_NOERR No error.
1599- * @return ::NC_EHDFERR HDF5 returned error.
1600- * @return ::NC_ENOMEM Out of memory.
1601- * @return ::NC_EATTMETA HDF5 can't open attribute.
1602- * @return ::NC_EBADTYPID Can't read attribute type.
1525+ * @return ::NC_NOERR No error. Iteration continues.
1526+ * @return ::-1 Error. Stop iteration.
1527+ * @author Ed Hartnett
16031528 */
16041529static herr_t
1605- att_read_var_callbk (hid_t loc_id , const char * att_name ,
1606- const H5A_info_t * ainfo , void * att_data )
1530+ att_read_callbk (hid_t loc_id , const char * att_name , const H5A_info_t * ainfo ,
1531+ void * att_data )
16071532{
16081533
16091534 hid_t attid = 0 ;
1610- int retval = NC_NOERR ;
16111535 NC_ATT_INFO_T * att ;
1536+ NCindex * list ;
16121537 att_iter_info * att_info = (att_iter_info * )att_data ;
1538+ int retval = NC_NOERR ;
1539+
1540+ /* Determin what list is being added to. */
1541+ list = att_info -> var ? att_info -> var -> att : att_info -> grp -> att ;
1542+
1543+ /* This may be an attribute telling us that strict netcdf-3 rules
1544+ * are in effect. If so, we will make note of the fact, but not add
1545+ * this attribute to the metadata. It's not a user attribute, but
1546+ * an internal netcdf-4 one. */
1547+ if (!strcmp (att_name , NC3_STRICT_ATT_NAME ))
1548+ {
1549+ /* Only relevant for groups, not vars. */
1550+ if (!att_info -> var )
1551+ att_info -> grp -> nc4_info -> cmode |= NC_CLASSIC_MODEL ;
1552+ return NC_NOERR ;
1553+ }
16131554
16141555 /* Should we ignore this attribute? */
1615- const NC_reservedatt * ra = NC_findreserved (att_name );
1616- if ( ra != NULL ) goto exit ; /* ignore */
1556+ if ( NC_findreserved (att_name ))
1557+ return NC_NOERR ;
16171558
16181559 /* Add to the end of the list of atts for this var. */
1619- if ((retval = nc4_att_list_add (att_info -> var -> att , att_name , & att )))
1620- BAIL (retval );
1560+ if ((retval = nc4_att_list_add (list , att_name , & att )))
1561+ BAIL (-1 );
16211562
16221563 /* Open the att by name. */
16231564 if ((attid = H5Aopen (loc_id , att_name , H5P_DEFAULT )) < 0 )
1624- BAIL (NC_EATTMETA );
1565+ BAIL (-1 );
16251566 LOG ((4 , "%s:: att_name %s" , __func__ , att_name ));
16261567
16271568 /* Read the rest of the info about the att,
@@ -1632,54 +1573,62 @@ att_read_var_callbk(hid_t loc_id, const char *att_name,
16321573 if (att )
16331574 att -> created = NC_TRUE ;
16341575
1635- if (attid > 0 && H5Aclose (attid ) < 0 )
1636- BAIL2 (NC_EHDFERR );
1637-
1638- return NC_NOERR ;
1639-
16401576exit :
1641- if (retval ) {
1642- if (retval == NC_EBADTYPID ) {
1643- /* NC_EBADTYPID will be normally converted to NC_NOERR so that
1644- the parent iterator does not fail. */
1645- retval = nc4_att_list_del (att_info -> var -> att ,att );
1646- att = NULL ;
1647- }
1577+ if (retval == NC_EBADTYPID )
1578+ {
1579+ /* NC_EBADTYPID will be normally converted to NC_NOERR so that
1580+ the parent iterator does not fail. */
1581+ retval = nc4_att_list_del (list , att );
1582+ att = NULL ;
16481583 }
16491584 if (attid > 0 && H5Aclose (attid ) < 0 )
1650- retval = NC_EHDFERR ;
1585+ retval = -1 ;
1586+
1587+ /* Since this is a HDF5 iterator callback, return -1 for any error
1588+ * to stop iteration. */
1589+ if (retval )
1590+ retval = -1 ;
16511591 return retval ;
16521592}
16531593
16541594/**
1655- * @internal This function reads all the attributes of a variable.
1595+ * @internal This function reads all the attributes of a variable or
1596+ * the global attributes of a group.
16561597 *
16571598 * @param grp Pointer to the group info.
1658- * @param var Pointer to the var info.
1599+ * @param var Pointer to the var info. NULL for global att reads.
16591600 *
1660- * @return NC_NOERR No error.
1601+ * @return ::NC_NOERR No error.
1602+ * @return ::NC_EATTMETA Some error occured reading attributes.
16611603 * @author Ed Hartnett
16621604 */
16631605int
1664- nc4_read_var_atts (NC_GRP_INFO_T * grp , NC_VAR_INFO_T * var )
1606+ nc4_read_atts (NC_GRP_INFO_T * grp , NC_VAR_INFO_T * var )
16651607{
16661608 att_iter_info att_info ; /* Custom iteration information */
1609+ hid_t locid ; /* HDF5 location to read atts from. */
16671610
16681611 /* Check inputs. */
1669- assert (grp && var );
1612+ assert (grp );
16701613
1671- /* Assign var and grp in struct. */
1614+ /* Assign var and grp in struct. (var may be NULL). */
16721615 att_info .var = var ;
16731616 att_info .grp = grp ;
16741617
1675- /* Now read all the attributes of this variable, ignoring the
1676- ones that hold HDF5 dimension scale information. */
1677- if ((H5Aiterate2 (var -> hdf_datasetid , H5_INDEX_CRT_ORDER , H5_ITER_INC , NULL ,
1678- att_read_var_callbk , & att_info )) < 0 )
1618+ /* Determine where to read from in the HDF5 file. */
1619+ locid = var ? var -> hdf_datasetid : grp -> hdf_grpid ;
1620+
1621+ /* Now read all the attributes at this location, ignoring special
1622+ * netCDF hidden attributes. */
1623+ if ((H5Aiterate2 (locid , H5_INDEX_CRT_ORDER , H5_ITER_INC , NULL ,
1624+ att_read_callbk , & att_info )) < 0 )
16791625 return NC_EATTMETA ;
16801626
1681- /* Remember that we have read the atts for this var. */
1682- var -> atts_not_read = 0 ;
1627+ /* Remember that we have read the atts for this var or group. */
1628+ if (var )
1629+ var -> atts_not_read = 0 ;
1630+ else
1631+ grp -> atts_not_read = 0 ;
16831632
16841633 return NC_NOERR ;
16851634}
0 commit comments