From ca0a7c164e2e492d5c48d066bacf83a92e675c2e Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 23 Apr 1998 17:24:38 -0500 Subject: [svn-r361] Added Attribute (H5A) code. --- src/H5A.c | 1330 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/H5Apkg.h | 46 ++ src/H5Aprivate.h | 30 ++ src/H5Apublic.h | 47 ++ src/H5D.c | 15 +- src/H5Dpkg.h | 40 ++ src/H5Epublic.h | 2 + src/H5Iprivate.h | 1 + src/H5Ipublic.h | 1 + src/H5O.c | 4 +- src/H5Oattr.c | 560 +++++++++++++++++++++++ src/H5Oprivate.h | 8 + src/H5Osdspace.c | 2 +- src/H5S.c | 35 +- src/H5Sprivate.h | 1 + src/H5T.c | 4 +- src/H5Tpublic.h | 2 +- src/H5public.h | 1 + src/Makefile.in | 29 +- src/hdf5.h | 3 +- 20 files changed, 2124 insertions(+), 37 deletions(-) create mode 100644 src/H5A.c create mode 100644 src/H5Apkg.h create mode 100644 src/H5Aprivate.h create mode 100644 src/H5Apublic.h create mode 100644 src/H5Dpkg.h create mode 100644 src/H5Oattr.c diff --git a/src/H5A.c b/src/H5A.c new file mode 100644 index 0000000..342dd5f --- /dev/null +++ b/src/H5A.c @@ -0,0 +1,1330 @@ +/**************************************************************************** +* NCSA HDF * +* Software Development Group * +* National Center for Supercomputing Applications * +* University of Illinois at Urbana-Champaign * +* 605 E. Springfield, Champaign IL 61820 * +* * +* For conditions of distribution and use, see the accompanying * +* hdf/COPYING file. * +* * +****************************************************************************/ + +#ifdef RCSID +static char RcsId[] = "$Revision$"; +#endif + +/* $Id$ */ + +#define H5A_PACKAGE /*suppress error about including H5Apkg */ +#define H5D_PACKAGE /*suppress error about including H5Dpkg */ +#define H5T_PACKAGE /*suppress error about including H5Tpkg */ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ + +/* Private header files */ +#include /* Generic Functions */ +#include /* IDs */ +#include /* B-tree subclass names */ +#include /* Datasets */ +#include /* Groups */ +#include /* Datatypes */ +#include /* Error handling */ +#include /* Memory management */ +#include /* Property lists */ +#include /* Object Headers */ +#include /* Attributes */ + +#define PABLO_MASK H5A_mask + +/* Is the interface initialized? */ +static hbool_t interface_initialize_g = FALSE; +#define INTERFACE_INIT H5A_init_interface +static herr_t H5A_init_interface(void); + +/* PRIVATE PROTOTYPES */ +static void H5A_term_interface(void); +static hid_t H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, const H5S_t *space); +static hid_t H5A_open(H5G_entry_t *ent, unsigned idx); +static herr_t H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf); +static herr_t H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf); +static int H5A_get_index(H5G_entry_t *ent, const char *name); + + +/*-------------------------------------------------------------------------- +NAME + H5A_init_interface -- Initialize interface-specific information +USAGE + herr_t H5A_init_interface() + +RETURNS + SUCCEED/FAIL +DESCRIPTION + Initializes any interface-specific data or routines. + +--------------------------------------------------------------------------*/ +static herr_t +H5A_init_interface(void) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER(H5A_init_interface, FAIL); + + /* + * Register cleanup function. + */ + if ((ret_value = H5I_init_group(H5_ATTR, H5I_ATTRID_HASHSIZE, + H5A_RESERVED_ATOMS, + (herr_t (*)(void *)) H5A_close)) == FAIL) { + HRETURN_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, + "unable to initialize attribute group"); + } + + if (H5_add_exit(H5A_term_interface) < 0) { + HRETURN_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, + "unable to install atexit function"); + } + + FUNC_LEAVE(ret_value); +} + + +/*-------------------------------------------------------------------------- + NAME + H5A_term_interface + PURPOSE + Terminate various H5A objects + USAGE + void H5A_term_interface() + RETURNS + SUCCEED/FAIL + DESCRIPTION + Release any other resources allocated. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Can't report errors... + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static void +H5A_term_interface(void) +{ +} + + +/*-------------------------------------------------------------------------- + NAME + H5Acreate + PURPOSE + Creates a dataset as an attribute of another dataset or group + USAGE + hid_t H5Acreate (loc_id, name, datatype, dataspace, create_plist) + hid_t loc_id; IN: Object (dataset or group) to be attached to + const char *name; IN: Name of attribute to create + hid_t datatype; IN: ID of datatype for attribute + hid_t dataspace; IN: ID of dataspace for attribute + hid_t create_plist; IN: ID of creation property list (currently not used) + RETURNS + SUCCEED/FAIL + + ERRORS + + DESCRIPTION + This function creates an attribute which is attached to the object + specified with 'location_id'. The name specified with 'name' for each + attribute for an object must be unique for that object. The 'type_id' + and 'space_id' are created with the H5T and H5S interfaces respectively. + Currently only simple dataspaces are allowed for attribute dataspaces. + The 'create_plist_id' property list is currently un-used, but will be + used int the future for optional properties of attributes. The attribute + ID returned from this function must be released with H5Aclose or resource + leaks will develop. + The link created (see H5G API documentation for more information on + link types) is a hard link, so the attribute may be shared among datasets + and will not be removed from the file until the reference count for the + attribute is reduced to zero. + The location object may be either a group or a dataset, both of + which may have any sort of attribute. +--------------------------------------------------------------------------*/ +hid_t +H5Acreate(hid_t loc_id, const char *name, hid_t datatype, hid_t dataspace, + hid_t create_plist) +{ + void *obj = NULL; + H5G_entry_t *ent = NULL; + H5T_t *type = NULL; + H5S_t *space = NULL; + const H5D_create_t *create_parms = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER(H5Acreate, FAIL); + + /* check arguments */ + if (!(H5_DATASET != H5I_group(loc_id) || H5_GROUP != H5I_group(loc_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); + } + if (!name || !*name) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); + } + if (H5_DATATYPE != H5I_group(datatype) || + NULL == (type = H5I_object(datatype))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a type"); + } + if (H5_DATASPACE != H5I_group(dataspace) || + NULL == (space = H5I_object(dataspace))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space"); + } + if (create_plist >= 0) { + if (H5P_DATASET_CREATE != H5Pget_class(create_plist) || + NULL == (create_parms = H5I_object(create_plist))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset creation property list"); + } + } else { + create_parms = &H5D_create_dflt; + } + + /* Get the dataset or group's pointer */ + if(NULL == (obj = H5I_object(loc_id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); + if (H5_DATASET == H5I_group(loc_id)) + ent=&(((H5D_t *)obj)->ent); + else + ent=&(((H5G_t *)obj)->ent); + + /* Go do the real work for attaching the attribute to the dataset */ + ret_value=H5A_create(ent,name,type,space); + + FUNC_LEAVE(ret_value); +} /* H5Acreate() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_create + * + * Purpose: + * This is the guts of the H5Acreate function. + * Usage: + * hid_t H5A_create (ent, name, type, space) + * const H5G_entry_t *ent; IN: Pointer to symbol table entry for object to attribute + * const char *name; IN: Name of attribute + * H5T_t *type; IN: Datatype of attribute + * H5S_t *space; IN: Dataspace of attribute + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * April 2, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, const H5S_t *space) +{ + H5A_t *attr = NULL; + H5A_t *found_attr = NULL; + intn seq=0; + hid_t ret_value = FAIL; + + FUNC_ENTER(H5A_create, FAIL); + + /* check args */ + assert(ent); + assert(name); + assert(type); + assert(space); + + /* Build the attribute information */ + if((attr = H5MM_xcalloc(1, sizeof(H5A_t)))==NULL) + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "unable to allocate space for attribute info"); + attr->name=HDstrdup(name); + attr->dt=H5T_copy(type); + attr->ds=H5S_copy(space); + + /* Copy the symbol table entry */ + attr->ent=*ent; + + /* Compute the internal sizes */ + attr->dt_size=(H5O_DTYPE[0].raw_size)(attr->ent.file,type); + attr->ds_size=(H5O_SDSPACE[0].raw_size)(attr->ent.file,&(space->u.simple)); + attr->data_size=H5S_get_npoints(space)*H5T_get_size(type); + + /* Hold the symbol table entry (and file) open */ + if (H5O_open(&(attr->ent)) < 0) { + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to open"); + } + attr->ent_opened=1; + + /* Read in the existing attributes to check for duplicates */ + seq=0; + while((found_attr=H5O_read(&(attr->ent), H5O_ATTR, seq, NULL))!=NULL) + { + /* Compare found attribute name to new attribute name reject creation if names are the same */ + if(HDstrcmp(found_attr->name,attr->name)==0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, FAIL, + "attribute already exists"); + seq++; + } /* end while */ + + /* Create the attribute message and save the attribute index */ + if (H5O_modify(&(attr->ent), H5O_ATTR, H5O_NEW_MESG, 0, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, + "can't update attribute header messages"); + + /* Register the new attribute and get an ID for it */ + if ((ret_value = H5I_register(H5_ATTR, attr)) < 0) { + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to register attribute for ID"); + } + +done: + if (ret_value < 0) { + if(attr) + H5A_close(attr); + } + + FUNC_LEAVE(ret_value); +} /* H5A_create() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_get_index + PURPOSE + Determine the index of an attribute in an object header + USAGE + int H5A_get_index (ent, name) + H5G_entry_t *ent; IN: Symbol table entry of object + const char *name; IN: Name of dataset to find + RETURNS + non-negative on success, negative on failure + + ERRORS + + DESCRIPTION + This function determines the index of the attribute within an object + header. This is not stored in the attribute structure because it is only + a subjective measure and can change if attributes are deleted from the + object header. +--------------------------------------------------------------------------*/ +static int +H5A_get_index(H5G_entry_t *ent, const char *name) +{ + H5A_t *found_attr = NULL; + int ret_value = FAIL; + + FUNC_ENTER(H5A_get_index, FAIL); + + assert(ent); + assert(name); + + /* Look up the attribute for the object */ + ret_value=0; + while((found_attr=H5O_read(ent, H5O_ATTR, ret_value, NULL))!=NULL) + { + /* Compare found attribute name to new attribute name reject creation if names are the same */ + if(HDstrcmp(found_attr->name,name)==0) + break; + ret_value++; + } /* end while */ + if(found_attr==NULL) { + HRETURN_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, + "attribute not found"); + } + + FUNC_LEAVE(ret_value); +} /* H5A_get_index() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Aopen_name + PURPOSE + Opens an attribute for an object by looking up the attribute name + USAGE + hid_t H5Aopen_name (loc_id, name) + hid_t loc_id; IN: Object (dataset or group) to be attached to + const char *name; IN: Name of attribute to locate and open + RETURNS + ID of attribute on success, negative on failure + + ERRORS + + DESCRIPTION + This function opens an existing attribute for access. The attribute + name specified is used to look up the corresponding attribute for the + object. The attribute ID returned from this function must be released with + H5Aclose or resource leaks will develop. + The location object may be either a group or a dataset, both of + which may have any sort of attribute. +--------------------------------------------------------------------------*/ +hid_t +H5Aopen_name(hid_t loc_id, const char *name) +{ + H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */ + void *obj = NULL; + intn idx=0; + hid_t ret_value = FAIL; + + FUNC_ENTER(H5Aopen_name, FAIL); + + /* check arguments */ + if (!(H5_DATASET != H5I_group(loc_id) || H5_GROUP != H5I_group(loc_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); + } + if (!name || !*name) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); + } + + /* Get the dataset or group's pointer */ + if(NULL == (obj = H5I_object(loc_id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); + + /* Copy the object header entry for the object */ + if (H5_DATASET == H5I_group(loc_id)) + ent=&(((H5D_t *)obj)->ent); + else + ent=&(((H5G_t *)obj)->ent); + + /* Look up the attribute for the object */ + if((idx=H5A_get_index(ent,name))<0) + HRETURN_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "attribute not found"); + + /* Go do the real work for opening the attribute */ + ret_value=H5A_open(ent, (unsigned)idx); + + FUNC_LEAVE(ret_value); +} /* H5Aopen_name() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Aopen_idx + PURPOSE + Opens the n'th attribute for an object + USAGE + hid_t H5Aopen_idx (loc_id, idx) + hid_t loc_id; IN: Object (dataset or group) to be attached to + unsigned idx; IN: Index (0-based) attribute to open + RETURNS + ID of attribute on success, negative on failure + + ERRORS + + DESCRIPTION + This function opens an existing attribute for access. The attribute + index specified is used to look up the corresponding attribute for the + object. The attribute ID returned from this function must be released with + H5Aclose or resource leaks will develop. + The location object may be either a group or a dataset, both of + which may have any sort of attribute. +--------------------------------------------------------------------------*/ +hid_t +H5Aopen_idx(hid_t loc_id, unsigned idx) +{ + H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */ + void *obj = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER(H5Aopen_idx, FAIL); + + /* check arguments */ + if (!(H5_DATASET != H5I_group(loc_id) || H5_GROUP != H5I_group(loc_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); + } + + /* Get the dataset or group's pointer */ + if(NULL == (obj = H5I_object(loc_id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); + + /* Copy the object header entry for the object */ + if (H5_DATASET == H5I_group(loc_id)) + ent=&(((H5D_t *)obj)->ent); + else + ent=&(((H5G_t *)obj)->ent); + + /* Go do the real work for opening the attribute */ + ret_value=H5A_open(ent, idx); + + FUNC_LEAVE(ret_value); +} /* H5Aopen_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_open + * + * Purpose: + * This is the guts of the H5Aopen_xxx functions + * Usage: + * herr_t H5A_open (ent, idx) + * const H5G_entry_t *ent; IN: Pointer to symbol table entry for object to attribute + * unsigned idx; IN: index of attribute to open (0-based) + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * April 2, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hid_t +H5A_open(H5G_entry_t *ent, unsigned idx) +{ + H5A_t *attr = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER(H5A_open, FAIL); + + /* check args */ + assert(ent); + + /* Build the attribute information */ + if((attr = H5MM_xcalloc(1, sizeof(H5A_t)))==NULL) + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "unable to allocate space for attribute info"); + + /* Read in attribute with H5O_read() */ + if (NULL==(H5O_read(ent, H5O_ATTR, idx, attr))) { + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, + "unable to load attribute info from dataset header"); + } + + /* Copy the symbol table entry */ + attr->ent=*ent; + + /* Hold the symbol table entry (and file) open */ + if (H5O_open(&(attr->ent)) < 0) { + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open"); + } + attr->ent_opened=1; + + /* Register the new attribute and get an ID for it */ + if ((ret_value = H5I_register(H5_ATTR, attr)) < 0) { + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to register attribute for ID"); + } + +done: + if (ret_value < 0) { + if(attr) + H5A_close(attr); + } + + FUNC_LEAVE(ret_value); +} /* H5A_open() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Awrite + PURPOSE + Write out data to an attribute + USAGE + herr_t H5Awrite (attr_id, mem_dt, buf) + hid_t attr_id; IN: Attribute to write + hid_t mem_dt; IN: Memory datatype of buffer + void *buf; IN: Buffer of data to write + RETURNS + SUCCEED/FAIL + + ERRORS + + DESCRIPTION + This function writes a complete attribute to disk. +--------------------------------------------------------------------------*/ +herr_t +H5Awrite(hid_t attr_id, hid_t mem_dt, void *buf) +{ + H5A_t *attr = NULL; + const H5T_t *mem_type = NULL; + herr_t ret_value = FAIL; + + FUNC_ENTER(H5Awrite, FAIL); + + /* check arguments */ + if (H5_ATTR != H5I_group(attr_id) || + (NULL == (attr = H5I_object(attr_id)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); + } + if (H5_DATATYPE != H5I_group(mem_dt) || + NULL == (mem_type = H5I_object(mem_dt))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + if (NULL == buf) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer"); + } + + /* Go write the actual data to the attribute */ + if ((ret_value=H5A_write(attr,mem_type,buf))<0) { + HRETURN_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, + "can't write attribute"); + } + + FUNC_LEAVE(ret_value); +} /* H5Awrite() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_write + PURPOSE + Actually write out data to an attribute + USAGE + herr_t H5A_write (attr, mem_type, buf) + H5A_t *attr; IN: Attribute to write + const H5T_t *mem_type; IN: Memory datatype of buffer + void *buf; IN: Buffer of data to write + RETURNS + SUCCEED/FAIL + + ERRORS + + DESCRIPTION + This function writes a complete attribute to disk. +--------------------------------------------------------------------------*/ +static herr_t +H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf) +{ + uint8 *tconv_buf = NULL; /* data type conv buffer */ + size_t nelmts; /* elements in attribute */ + H5T_conv_t tconv_func = NULL; /* conversion function */ + H5T_cdata_t *cdata = NULL; /* type conversion data */ + hid_t src_id = -1, dst_id = -1;/* temporary type atoms */ + size_t src_type_size; /* size of source type */ + size_t dst_type_size; /* size of destination type*/ + size_t buf_size; /* desired buffer size */ + int idx; /* index of attribute in object header */ + herr_t ret_value = FAIL; + + FUNC_ENTER(H5A_write, FAIL); + + assert(attr); + assert(mem_type); + assert(buf); + + + /* Create buffer for data to store on disk */ + nelmts=H5S_get_npoints (attr->ds); + + /* Get the memory and file datatype sizes */ + src_type_size = H5T_get_size(mem_type); + dst_type_size = H5T_get_size(attr->dt); + + /* Get the maximum buffer size needed and allocate it */ + buf_size = nelmts*MAX(src_type_size,dst_type_size); + tconv_buf = H5MM_xmalloc (buf_size); + + /* Copy the user's data into the buffer for conversion */ + HDmemcpy(tconv_buf,buf,src_type_size*nelmts); + +/* Convert memory buffer into disk buffer */ + /* Set up type conversion function */ + if (NULL == (tconv_func = H5T_find(mem_type, attr->dt, + H5T_BKG_NO, &cdata))) { + HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, + "unable to convert between src and dest data types"); + } else if (H5T_conv_noop!=tconv_func) { + if ((src_id = H5I_register(H5_DATATYPE, H5T_copy(mem_type)))<0 || + (dst_id = H5I_register(H5_DATATYPE, H5T_copy(attr->dt)))<0) { + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, + "unable to register types for conversion"); + } + } + + /* Perform data type conversion. */ + cdata->command = H5T_CONV_CONV; + cdata->stats->ncalls++; + if ((tconv_func) (src_id, dst_id, cdata, nelmts, tconv_buf, NULL)<0) { + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, + "data type conversion failed"); + } + + /* Free the previous attribute data buffer, if there is one */ + if(attr->data) + H5MM_xfree(attr->data); + + /* Look up the attribute for the object */ + if((idx=H5A_get_index(&(attr->ent),attr->name))<0) + HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "attribute not found"); + + /* Modify the attribute data */ + attr->data=tconv_buf; /* Set the data pointer temporarily */ + if (H5O_modify(&(attr->ent), H5O_ATTR, idx, 0, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, + "can't update attribute header messages"); + attr->data=NULL; /* un-do the data pointer */ + + /* Indicate the the attribute doesn't need fill-values */ + attr->initialized=TRUE; + + ret_value=SUCCEED; + +done: + /* Release resources */ + if (src_id >= 0) + H5I_dec_ref(src_id); + if (dst_id >= 0) + H5I_dec_ref(dst_id); + if (tconv_buf) + H5MM_xfree(tconv_buf); + + FUNC_LEAVE(ret_value); +} /* H5A_write() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Aread + PURPOSE + Read in data from an attribute + USAGE + herr_t H5Aread (attr_id, mem_dt, buf) + hid_t attr_id; IN: Attribute to read + hid_t mem_dt; IN: Memory datatype of buffer + void *buf; IN: Buffer for data to read + RETURNS + SUCCEED/FAIL + + ERRORS + + DESCRIPTION + This function reads a complete attribute from disk. +--------------------------------------------------------------------------*/ +herr_t +H5Aread(hid_t attr_id, hid_t mem_dt, void *buf) +{ + H5A_t *attr = NULL; + const H5T_t *mem_type = NULL; + herr_t ret_value = FAIL; + + FUNC_ENTER(H5Aread, FAIL); + + /* check arguments */ + if (H5_ATTR != H5I_group(attr_id) || + (NULL == (attr = H5I_object(attr_id)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); + } + if (H5_DATATYPE != H5I_group(mem_dt) || + NULL == (mem_type = H5I_object(mem_dt))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); + } + if (NULL == buf) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer"); + } + + /* Go write the actual data to the attribute */ + if ((ret_value=H5A_read(attr,mem_type,buf))<0) { + HRETURN_ERROR(H5E_ATTR, H5E_READERROR, FAIL, + "can't read attribute"); + } + + FUNC_LEAVE(ret_value); +} /* H5Aread() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_read + PURPOSE + Actually read in data from an attribute + USAGE + herr_t H5A_read (attr, mem_type, buf) + H5A_t *attr; IN: Attribute to read + const H5T_t *mem_type; IN: Memory datatype of buffer + void *buf; IN: Buffer for data to read + RETURNS + SUCCEED/FAIL + + ERRORS + + DESCRIPTION + This function read a complete attribute to disk. +--------------------------------------------------------------------------*/ +static herr_t +H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf) +{ + uint8 *tconv_buf = NULL; /* data type conv buffer */ + size_t nelmts; /* elements in attribute */ + H5T_conv_t tconv_func = NULL; /* conversion function */ + H5T_cdata_t *cdata = NULL; /* type conversion data */ + hid_t src_id = -1, dst_id = -1;/* temporary type atoms */ + size_t src_type_size; /* size of source type */ + size_t dst_type_size; /* size of destination type*/ + size_t buf_size; /* desired buffer size */ + herr_t ret_value = FAIL; + + FUNC_ENTER(H5A_read, FAIL); + + assert(attr); + assert(mem_type); + assert(buf); + + + /* Create buffer for data to store on disk */ + nelmts=H5S_get_npoints (attr->ds); + + /* Get the memory and file datatype sizes */ + src_type_size = H5T_get_size(attr->dt); + dst_type_size = H5T_get_size(mem_type); + + /* Get the maximum buffer size needed and allocate it */ + buf_size = nelmts*MAX(src_type_size,dst_type_size); + tconv_buf = H5MM_xmalloc (buf_size); + + /* Copy the attribute data into the buffer for conversion */ + HDmemcpy(tconv_buf,attr->data,src_type_size*nelmts); + +/* Convert memory buffer into disk buffer */ + /* Set up type conversion function */ + if (NULL == (tconv_func = H5T_find(attr->dt, mem_type, + H5T_BKG_NO, &cdata))) { + HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, + "unable to convert between src and dest data types"); + } else if (H5T_conv_noop!=tconv_func) { + if ((src_id = H5I_register(H5_DATATYPE, H5T_copy(attr->dt)))<0 || + (dst_id = H5I_register(H5_DATATYPE, H5T_copy(mem_type)))<0) { + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, + "unable to register types for conversion"); + } + } + + /* Perform data type conversion. */ + cdata->command = H5T_CONV_CONV; + cdata->stats->ncalls++; + if ((tconv_func) (src_id, dst_id, cdata, nelmts, tconv_buf, NULL)<0) { + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, + "data type conversion failed"); + } + + /* Copy the converted data into the user's buffer */ + HDmemcpy(buf,tconv_buf,dst_type_size*nelmts); + + + ret_value=SUCCEED; + +done: + /* Release resources */ + if (src_id >= 0) + H5I_dec_ref(src_id); + if (dst_id >= 0) + H5I_dec_ref(dst_id); + if (tconv_buf) + H5MM_xfree(tconv_buf); + + FUNC_LEAVE(ret_value); +} /* H5A_read() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Aget_space + PURPOSE + Gets a copy of the dataspace for an attribute + USAGE + hid_t H5Aget_space (attr_id) + hid_t attr_id; IN: Attribute to get dataspace of + RETURNS + A dataspace ID on success, negative on failure + + ERRORS + + DESCRIPTION + This function retrieves a copy of the dataspace for an attribute. + The dataspace ID returned from this function must be released with H5Sclose + or resource leaks will develop. +--------------------------------------------------------------------------*/ +hid_t +H5Aget_space(hid_t attr_id) +{ + H5A_t *attr = NULL; + H5S_t *dst = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER(H5Aget_space, FAIL); + + /* check arguments */ + if (H5_ATTR != H5I_group(attr_id) || + (NULL == (attr = H5I_object(attr_id)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); + } + + /* Copy the attribute's dataspace */ + if (NULL==(dst=H5S_copy (attr->ds))) { + HRETURN_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, + "unable to copy dataspace"); + } + + /* Atomize */ + if ((ret_value=H5I_register (H5_DATASPACE, dst))<0) { + HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to register dataspace atom"); + } + + FUNC_LEAVE(ret_value); +} /* H5Aget_space() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Aget_type + PURPOSE + Gets a copy of the datatype for an attribute + USAGE + hid_t H5Aget_type (attr_id) + hid_t attr_id; IN: Attribute to get datatype of + RETURNS + A datatype ID on success, negative on failure + + ERRORS + + DESCRIPTION + This function retrieves a copy of the datatype for an attribute. + The datatype ID returned from this function must be released with H5Tclose + or resource leaks will develop. +--------------------------------------------------------------------------*/ +hid_t +H5Aget_type(hid_t attr_id) +{ + H5A_t *attr = NULL; + H5T_t *dst = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER(H5Aget_type, FAIL); + + /* check arguments */ + if (H5_ATTR != H5I_group(attr_id) || + (NULL == (attr = H5I_object(attr_id)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); + } + + /* Copy the attribute's dataspace */ + if (NULL==(dst=H5T_copy (attr->dt))) { + HRETURN_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, + "unable to copy datatype"); + } + + /* Atomize */ + if ((ret_value=H5I_register (H5_DATATYPE, dst))<0) { + HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to register datatype atom"); + } + + FUNC_LEAVE(ret_value); +} /* H5Aget_type() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Aget_name + PURPOSE + Gets a copy of the name for an attribute + USAGE + size_t H5Aget_name (attr_id, buf, buf_size) + hid_t attr_id; IN: Attribute to get name of + char *buf; IN: Buffer to store name in + size_t buf_size; IN: The size of the buffer to store the string in. + RETURNS + This function returns the length of the attribute's name (which may be + longer than 'buf_size') on success or negative for failure. + + ERRORS + + DESCRIPTION + This function retrieves the name of an attribute for an attribute ID. + Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string + terminator. If the name of the attribute is longer than 'buf_size'-1, + the string terminator is stored in the last position of the buffer to + properly terminate the string. +--------------------------------------------------------------------------*/ +size_t +H5Aget_name(hid_t attr_id, char *buf, size_t buf_size) +{ + H5A_t *attr = NULL; + size_t copy_len=0; + size_t ret_value = FAIL; + + FUNC_ENTER(H5Aget_name, FAIL); + + /* check arguments */ + if (H5_ATTR != H5I_group(attr_id) || + (NULL == (attr = H5I_object(attr_id)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); + } + if (!buf || buf_size==0) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer"); + } + + /* get the real attribute length */ + ret_value=HDstrlen(attr->name); + + /* compute the string length which will fit into the user's buffer */ + copy_len=MIN(buf_size-1,ret_value); + + /* Copy all/some of the name */ + HDmemcpy(buf,attr->name,copy_len); + + /* Terminate the string */ + buf[copy_len]='\0'; + + FUNC_LEAVE(ret_value); +} /* H5Aget_type() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Anum_attrs + PURPOSE + Determines the number of attributes attached to an object + USAGE + int H5Anum_attrs (loc_id) + hid_t loc_id; IN: Object (dataset or group) to be queried + RETURNS + Number of attributes on success, negative on failure + + ERRORS + + DESCRIPTION + This function returns the number of attributes attached to a dataset or + group, 'location_id'. +--------------------------------------------------------------------------*/ +int +H5Anum_attrs(hid_t loc_id) +{ + H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */ + void *obj = NULL; + int ret_value = 0; + + FUNC_ENTER(H5Anum_attrs, FAIL); + + /* check arguments */ + if (!(H5_DATASET != H5I_group(loc_id) || H5_GROUP != H5I_group(loc_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); + } + + /* Get the dataset or group's pointer */ + if(NULL == (obj = H5I_object(loc_id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); + + /* Copy the object header entry for the object */ + if (H5_DATASET == H5I_group(loc_id)) + ent=&(((H5D_t *)obj)->ent); + else + ent=&(((H5G_t *)obj)->ent); + + /* Look up the attribute for the object */ + ret_value=H5O_count(ent, H5O_ATTR); + + FUNC_LEAVE(ret_value); +} /* H5Anum_attrs() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Aiterate + PURPOSE + Calls a user's function for each attribute on an object + USAGE + herr_t H5Aiterate (loc_id, attr_num, op, data) + hid_t loc_id; IN: Object (dataset or group) to be iterated over + unsigned *attr_num; IN/OUT: Starting (IN) & Ending (OUT) attribute number + H5A_operator_t op; IN: User's function to pass each attribute to + void *op_data; IN/OUT: User's data to pass through to iterator operator function + RETURNS + Returns a negative value if something is wrong, the return value of the + last operator if it was non-zero, or zero if all attributes were processed. + + ERRORS + + DESCRIPTION + This function interates over the attributes of dataset or group + specified with 'loc_id'. For each attribute of the object, the + 'op_data' and some additional information (specified below) are passed + to the 'op' function. The iteration begins with the '*attr_number' + object in the group and the next attribute to be processed by the operator + is returned in '*attr_number'. + The operation receives the ID for the group or dataset being iterated + over ('loc_id'), the name of the current attribute about the object + ('attr_name') and the pointer to the operator data passed in to H5Aiterate + ('op_data'). The return values from an operator are: + A. Zero causes the iterator to continue, returning zero when all + attributes have been processed. + B. Positive causes the iterator to immediately return that positive + value, indicating short-circuit success. The iterator can be + restarted at the next attribute. + C. Negative causes the iterator to immediately return that value, + indicating failure. The iterator can be restarted at the next + attribute. +--------------------------------------------------------------------------*/ +int +H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op, void *op_data) +{ + H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */ + void *obj = NULL; + H5A_t *found_attr = NULL; + int ret_value = 0; + + FUNC_ENTER(H5Anum_attrs, FAIL); + + /* check arguments */ + if (!(H5_DATASET != H5I_group(loc_id) || H5_GROUP != H5I_group(loc_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); + } + if (!attr_num) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index"); + } + if (!op) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid operator"); + } + + /* Get the dataset or group's pointer */ + if(NULL == (obj = H5I_object(loc_id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); + + /* Copy the object header entry for the object */ + if (H5_DATASET == H5I_group(loc_id)) + ent=&(((H5D_t *)obj)->ent); + else + ent=&(((H5G_t *)obj)->ent); + + /* Look up the attribute for the object */ + if((int)*attr_numname,op_data))!=0) + break; + } /* end while */ + + FUNC_LEAVE(ret_value); +} /* H5Aiterate() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Adelete + PURPOSE + Deletes an attribute from a location + USAGE + herr_t H5Adelete (loc_id, name) + hid_t loc_id; IN: Object (dataset or group) to have attribute deleted from + const char *name; IN: Name of attribute to delete + RETURNS + 0 on success, negative on failure + + ERRORS + + DESCRIPTION + This function removes the named attribute from a dataset or group. + This function should not be used when attribute IDs are open on 'loc_id' + as it may cause the internal indexes of the attributes to change and future + writes to the open attributes to produce incorrect results. +--------------------------------------------------------------------------*/ +herr_t +H5Adelete(hid_t loc_id, const char *name) +{ + H5A_t *found_attr = NULL; + H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */ + void *obj = NULL; + intn idx=0; + hid_t ret_value = FAIL; + + FUNC_ENTER(H5Aopen_name, FAIL); + + /* check arguments */ + if (!(H5_DATASET != H5I_group(loc_id) || H5_GROUP != H5I_group(loc_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute target not a dataset or group"); + } + if (!name || !*name) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); + } + + /* Get the dataset or group's pointer */ + if(NULL == (obj = H5I_object(loc_id))) + HRETURN_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom"); + + /* Copy the object header entry for the object */ + if (H5_DATASET == H5I_group(loc_id)) + ent=&(((H5D_t *)obj)->ent); + else + ent=&(((H5G_t *)obj)->ent); + + /* Look up the attribute for the object */ + idx=0; + while((found_attr=H5O_read(ent, H5O_ATTR, idx, NULL))!=NULL) + { + /* Compare found attribute name to new attribute name reject creation if names are the same */ + if(HDstrcmp(found_attr->name,name)==0) + break; + idx++; + } /* end while */ + if(found_attr==NULL) { + HRETURN_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, + "attribute not found"); + } + + /* Delete the attribute from the location */ + if ((ret_value=H5O_remove(ent, H5O_ATTR, idx)) < 0) + HRETURN_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, + "can't delete attribute header message"); + + FUNC_LEAVE(ret_value); +} /* H5Adelete() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Aclose + PURPOSE + Close an attribute ID + USAGE + herr_t H5Aclose (attr_id) + hid_t attr_id; IN: Attribute to release access to + RETURNS + SUCCEED/FAIL + + ERRORS + + DESCRIPTION + This function releases an attribute from use. Further use of the + attribute ID will result in undefined behavior. +--------------------------------------------------------------------------*/ +herr_t +H5Aclose(hid_t attr_id) +{ + H5A_t *attr = NULL; + herr_t ret_value = FAIL; + + FUNC_ENTER(H5Aclose, FAIL); + + /* check arguments */ + if (H5_ATTR != H5I_group(attr_id) || + (NULL == (attr = H5I_object(attr_id)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute"); + } + + /* Check if the attribute has any data yet, if not, fill with zeroes */ + if(!attr->initialized) { + uint8 *tmp_buf=H5MM_xcalloc(1,attr->data_size); + + if (NULL == tmp_buf) { + HRETURN_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, + "can't allocate attribute fill-value"); + } + + /* Go write the fill data to the attribute */ + if ((ret_value=H5A_write(attr,attr->dt,tmp_buf))<0) { + HRETURN_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, + "can't write attribute"); + } + + /* Free temporary buffer */ + H5MM_xfree(tmp_buf); + } /* end if */ + + /* Free the memory used for the attribute */ + H5A_close(attr); + ret_value=SUCCEED; + + FUNC_LEAVE(ret_value); +} /* H5Aclose() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_copy + * + * Purpose: Copies attribute OLD_ATTR. + * + * Return: Success: Pointer to a new copy of the OLD_ATTR argument. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Thursday, December 4, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5A_t * +H5A_copy(const H5A_t *old_attr) +{ + H5A_t *new_attr=NULL; + + FUNC_ENTER(H5A_copy, NULL); + + /* check args */ + assert(old_attr); + + /* get space */ + new_attr = H5MM_xcalloc(1, sizeof(H5A_t)); + + /* Copy the top level of the attribute */ + *new_attr = *old_attr; + + /* Don't open the object header for a copy */ + new_attr->ent_opened=0; + + /* Copy the guts of the attribute */ + new_attr->name=HDstrdup(old_attr->name); + new_attr->dt=H5T_copy(old_attr->dt); + new_attr->ds=H5S_copy(old_attr->ds); + if(old_attr->data) { + new_attr->data=H5MM_xmalloc(old_attr->data_size); + HDmemcpy(new_attr->data,old_attr->data,old_attr->data_size); + } /* end if */ + + /* Copy the share info? */ + + FUNC_LEAVE(new_attr); +} + + +/*------------------------------------------------------------------------- + * Function: H5A_close + * + * Purpose: Frees a attribute and all associated memory. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Monday, December 8, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5A_close(H5A_t *attr) +{ + FUNC_ENTER(H5A_close, FAIL); + + assert(attr); + + /* Free dynamicly allocated items */ + if(attr->name) + H5MM_xfree(attr->name); + if(attr->dt) + H5T_close(attr->dt); + if(attr->ds) + H5S_close(attr->ds); + if(attr->data) + H5MM_xfree(attr->data); + + /* Close the object's symbol-table entry */ + if(attr->ent_opened) + H5O_close(&(attr->ent)); + +/* Do something with the shared information? */ + + H5MM_xfree(attr); + + FUNC_LEAVE(SUCCEED); +} + diff --git a/src/H5Apkg.h b/src/H5Apkg.h new file mode 100644 index 0000000..b6f1a24 --- /dev/null +++ b/src/H5Apkg.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 1997 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke + * Monday, December 8, 1997 + * + * Purpose: This file contains declarations which are visible only within + * the H5A package. Source files outside the H5A package should + * include H5Aprivate.h instead. + */ +#ifndef H5A_PACKAGE +#error "Do not include this file outside the H5A package!" +#endif + +#ifndef _H5Apkg_H +#define _H5Apkg_H + +/* + * Define this to enable debugging. + */ +#ifdef NDEBUG +# undef H5A_DEBUG +#endif + +#include +#include + +struct H5A_t { + uintn initialized;/* Indicate whether the attribute has been modified */ + uintn ent_opened; /* Object header entry opened? */ + H5G_entry_t ent; /* Object Header entry (for both datasets & groups) */ + char *name; /* Attribute's name */ + H5T_t *dt; /* Attribute's datatype */ + size_t dt_size; /* Size of datatype on disk */ + H5S_t *ds; /* Attribute's dataspace */ + size_t ds_size; /* Size of dataspace on disk */ + void *data; /* Attribute data (on a temporary basis) */ + size_t data_size; /* Size of data on disk */ + H5HG_t sh_heap; /*if defined, attribute is in global heap */ + H5F_t *sh_file; /*file pointer if this is a shared attribute */ +}; + +/* Function prototypes for H5T package scope */ + +#endif diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h new file mode 100644 index 0000000..9557ddd --- /dev/null +++ b/src/H5Aprivate.h @@ -0,0 +1,30 @@ +/**************************************************************************** + * NCSA HDF * + * Software Development Group * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + +/* + * This file contains private information about the H5D module + */ +#ifndef _H5Aprivate_H +#define _H5Aprivate_H + +#include + +#define H5A_RESERVED_ATOMS 0 +typedef struct H5A_t H5A_t; + +/* Private headers needed by this file */ + +/* Functions defined in H5A.c */ +H5A_t * H5A_copy(const H5A_t *old_attr); +herr_t H5A_close(H5A_t *attr); + +#endif diff --git a/src/H5Apublic.h b/src/H5Apublic.h new file mode 100644 index 0000000..71322dc --- /dev/null +++ b/src/H5Apublic.h @@ -0,0 +1,47 @@ +/**************************************************************************** + * NCSA HDF * + * Software Development Group * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + +/* + * This file contains public declarations for the H5A module. + */ +#ifndef _H5Apublic_H +#define _H5Apublic_H + +/* Public headers needed by this file */ + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*H5A_operator_t)(hid_t location_id/*in*/, + const char *attr_name/*in*/, void *operator_data/*in,out*/); + +/* Public function prototypes */ +hid_t H5Acreate(hid_t loc_id, const char *name, hid_t datatype, hid_t dataspace, hid_t create_plist); +hid_t H5Aopen_name(hid_t loc_id, const char *name); +hid_t H5Aopen_idx(hid_t loc_id, unsigned idx); +herr_t H5Awrite(hid_t attr_id, hid_t mem_dt, void *buf); +herr_t H5Aread(hid_t attr_id, hid_t mem_dt, void *buf); +herr_t H5Aclose(hid_t attr_id); +hid_t H5Aget_space(hid_t attr); +hid_t H5Aget_type(hid_t attr); +size_t H5Aget_name(hid_t attr, char *buf, size_t buf_size); +int H5Anum_attrs(hid_t loc_id); +int H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op, void *op_data); +herr_t H5Adelete(hid_t loc_id, const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* _H5Apublic_H */ diff --git a/src/H5D.c b/src/H5D.c index 45ed334..17a5c7d 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -14,12 +14,12 @@ static char RcsId[] = "@(#)$Revision$"; #endif -/* $Id$ */ +#define H5D_PACKAGE /*suppress error about including H5Tpkg */ #include /* Generic Functions */ #include /* IDs */ #include /* Cache */ -#include /* Dataset functions */ +#include /* Dataset functions */ #include /* Error handling */ #include /* Group headers */ #include /* Name heap */ @@ -37,17 +37,6 @@ static char RcsId[] = "@(#)$Revision$"; */ #define H5D_OPTIMIZE_PIPE 1 -/* - * A dataset is the following struct. - */ -struct H5D_t { - H5G_entry_t ent; /*cached object header stuff */ - H5T_t *type; /*datatype of this dataset */ - H5S_t *space; /*dataspace of this dataset */ - H5D_create_t *create_parms; /*creation parameters */ - H5O_layout_t layout; /*data layout */ -}; - /* Default dataset creation property list */ const H5D_create_t H5D_create_dflt = { H5D_CONTIGUOUS, /* Layout */ diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h new file mode 100644 index 0000000..e57f6ab --- /dev/null +++ b/src/H5Dpkg.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 1997 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke + * Monday, December 8, 1997 + * + * Purpose: This file contains declarations which are visible only within + * the H5D package. Source files outside the H5D package should + * include H5Dprivate.h instead. + */ +#ifndef H5D_PACKAGE +#error "Do not include this file outside the H5D package!" +#endif + +#ifndef _H5Dpkg_H +#define _H5Dpkg_H + +/* + * Define this to enable debugging. + */ +#ifdef NDEBUG +# undef H5D_DEBUG +#endif + +#include + +/* + * A dataset is the following struct. + */ +struct H5D_t { + H5G_entry_t ent; /*cached object header stuff */ + H5T_t *type; /*datatype of this dataset */ + H5S_t *space; /*dataspace of this dataset */ + H5D_create_t *create_parms; /*creation parameters */ + H5O_layout_t layout; /*data layout */ +}; + + +#endif diff --git a/src/H5Epublic.h b/src/H5Epublic.h index 284b310..9a07ad5 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -46,6 +46,7 @@ typedef enum H5E_major_t { H5E_DATASET, /*Dataset */ H5E_STORAGE, /*data storage */ H5E_TEMPLATE, /*Property lists */ + H5E_ATTR, /*Attribute */ H5E_COMP, /*Data compression */ H5E_EFL /*External file list */ } H5E_major_t; @@ -108,6 +109,7 @@ typedef enum H5E_minor_t { H5E_VERSION, /*wrong version number */ H5E_ALIGNMENT, /*alignment error */ H5E_BADMESG, /*unrecognized message */ + H5E_CANTDELETE, /* Can't delete message */ /* Group related errors */ H5E_CANTOPENOBJ, /*Can't open object */ diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h index 25fe0c7..895128b 100644 --- a/src/H5Iprivate.h +++ b/src/H5Iprivate.h @@ -67,6 +67,7 @@ #define H5I_DATASETID_HASHSIZE 64 #define H5I_OID_HASHSIZE 64 #define H5I_GROUPID_HASHSIZE 64 +#define H5I_ATTRID_HASHSIZE 64 /* Atom information structure used */ typedef struct H5I_id_info_t { diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index bb1dfc4..eb8b804 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -40,6 +40,7 @@ typedef enum { H5_DATASPACE, /*group ID for Dataspace objects */ H5_DATASET, /*group ID for Dataset objects */ H5_DIRECTORY, /*group ID for Directory objects */ + H5_ATTR, /*group ID for Attribute objects */ MAXGROUP /*highest group in group_t (Invalid as true group)*/ } H5I_group_t; diff --git a/src/H5O.c b/src/H5O.c index a027bf0..9bf528c 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -62,7 +62,7 @@ static const H5O_class_t *const message_type_g[] = { NULL, /*0x0009 Not assigned */ NULL, /*0x000A Not assigned */ H5O_COMPRESS, /*0x000B Data storage -- compressed object */ - NULL, /*0x000C Attribute list */ + H5O_ATTR, /*0x000C Attribute list */ H5O_NAME, /*0x000D Object name */ NULL, /*0x000E Object modification date and time */ NULL, /*0x000F Shared header message */ @@ -975,7 +975,7 @@ H5O_find_in_ohdr(H5F_t *f, const haddr_t *addr, const H5O_class_t **type_p, * * The OVERWRITE argument is either a sequence number of a * message to overwrite (usually zero) or the constant - * H5O_NEW_MESSAGE (-1) to indicate that a new message is to + * H5O_NEW_MESG (-1) to indicate that a new message is to * be created. If the message to overwrite doesn't exist then * it is created (but only if it can be inserted so its sequence * number is OVERWRITE; that is, you can create a message with diff --git a/src/H5Oattr.c b/src/H5Oattr.c new file mode 100644 index 0000000..2671b38 --- /dev/null +++ b/src/H5Oattr.c @@ -0,0 +1,560 @@ +/**************************************************************************** +* NCSA HDF * +* Software Development Group * +* National Center for Supercomputing Applications * +* University of Illinois at Urbana-Champaign * +* 605 E. Springfield, Champaign IL 61820 * +* * +* For conditions of distribution and use, see the accompanying * +* hdf/COPYING file. * +* * +****************************************************************************/ + +#ifdef RCSID +static char RcsId[] = "@(#)$Revision$"; +#endif + +/* $Id$ */ + +#define H5A_PACKAGE /*prevent warning from including H5Tpkg.h */ + +#include +#include +#include +#include +#include +#include + +#define PABLO_MASK H5O_attr_mask + +/* PRIVATE PROTOTYPES */ +static herr_t H5O_attr_encode (H5F_t *f, uint8 *p, const void *mesg); +static void *H5O_attr_decode (H5F_t *f, const uint8 *p, H5HG_t *hobj); +static void *H5O_attr_copy (const void *_mesg, void *_dest); +static size_t H5O_attr_size (H5F_t *f, const void *_mesg); +static herr_t H5O_attr_reset (void *_mesg); +static herr_t H5O_attr_debug (H5F_t *f, const void *_mesg, + FILE * stream, intn indent, intn fwidth); + +/* This message derives from H5O */ +const H5O_class_t H5O_ATTR[1] = {{ + H5O_ATTR_ID, /* message id number */ + "attribute", /* message name for debugging */ + sizeof(H5A_t), /* native message size */ + H5O_attr_decode, /* decode message */ + H5O_attr_encode, /* encode message */ + H5O_attr_copy, /* copy the native value */ + H5O_attr_size, /* size of raw message */ + H5O_attr_reset, /* reset method */ + NULL, /* no share method (currently) */ + H5O_attr_debug, /* debug the message */ +}}; + +/* Interface initialization */ +static hbool_t interface_initialize_g = FALSE; +#define INTERFACE_INIT NULL + +/*-------------------------------------------------------------------------- + NAME + H5O_attr_decode + PURPOSE + Decode a attribute message and return a pointer to a memory struct + with the decoded information + USAGE + void *H5O_attr_decode(f, raw_size, p) + H5F_t *f; IN: pointer to the HDF5 file struct + size_t raw_size; IN: size of the raw information buffer + const uint8 *p; IN: the raw information buffer + RETURNS + Pointer to the new message in native order on success, NULL on failure + DESCRIPTION + This function decodes the "raw" disk form of a attribute message + into a struct in memory native format. The struct is allocated within this + function using malloc() and is returned to the caller. +--------------------------------------------------------------------------*/ +static void * +H5O_attr_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj) +{ + H5A_t *attr = NULL; + H5S_simple_t *simple; /*simple dimensionality information */ + size_t name_len; /* Attribute name length */ + + FUNC_ENTER(H5O_attr_decode, NULL); + + /* check args */ + assert(f); + assert(p); + + attr = H5MM_xcalloc(1, sizeof(H5A_t)); + + /* Decode and store the name */ + UINT16DECODE(p, name_len); + attr->name=H5MM_xmalloc(name_len+1); + HDmemcpy(attr->name,p,name_len); + attr->name[name_len]='\0'; + p+=name_len; /* advance the memory pointer */ + + /* decode the attribute datatype */ + if((attr->dt=(H5O_DTYPE[0].decode)(f,p,NULL))==NULL) { + HRETURN_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, + "can't decode attribute datatype"); + } + attr->dt_size=(H5O_DTYPE[0].raw_size)(f,attr->dt); + p+=attr->dt_size; + + /* decode the attribute dataspace */ + attr->ds = H5MM_xcalloc(1, sizeof(H5S_t)); + if((simple=(H5O_SDSPACE[0].decode)(f,p,NULL))!=NULL) { + attr->ds->type = H5S_SIMPLE; + HDmemcpy(&(attr->ds->u.simple),simple, sizeof(H5S_simple_t)); + H5MM_xfree(simple); + } else { + attr->ds->type = H5S_SCALAR; + } /* end else */ + attr->ds_size=(H5O_SDSPACE[0].raw_size)(f,&(attr->ds->u.simple)); + p+=attr->ds_size; + + /* Compute the size of the data */ + attr->data_size=H5S_get_npoints(attr->ds)*H5T_get_size(attr->dt); + + /* Go get the data */ + attr->data = H5MM_xmalloc(attr->data_size); + HDmemcpy(attr->data,p,attr->data_size); + + /* Indicate that the fill values aren't to be written out */ + attr->initialized=1; + +#ifdef LOTSLATER + if (hobj) { + attr->sh_heap = *hobj; + attr->sh_file = f; + } +#endif + + FUNC_LEAVE(attr); +} + +/*-------------------------------------------------------------------------- + NAME + H5O_attr_encode + PURPOSE + Encode a simple attribute message + USAGE + herr_t H5O_attr_encode(f, raw_size, p, mesg) + H5F_t *f; IN: pointer to the HDF5 file struct + const uint8 *p; IN: the raw information buffer + const void *mesg; IN: Pointer to the simple datatype struct + RETURNS + SUCCEED/FAIL + DESCRIPTION + This function encodes the native memory form of the attribute + message in the "raw" disk form. +--------------------------------------------------------------------------*/ +static herr_t +H5O_attr_encode(H5F_t *f, uint8 *p, const void *mesg) +{ + const H5A_t *attr = (const H5A_t *) mesg; + size_t name_len; /* Attribute name length */ + + FUNC_ENTER(H5O_attr_encode, FAIL); + + /* check args */ + assert(f); + assert(p); + assert(attr); + + /* encode the attribute name */ + name_len=HDstrlen(attr->name); + UINT16ENCODE(p, name_len); + HDmemcpy(p,attr->name,name_len); + p+=name_len; + + /* encode the attribute datatype */ + if((H5O_DTYPE[0].encode)(f,p,attr->dt)<0) { + HRETURN_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, + "can't encode attribute datatype"); + } + p+=attr->dt_size; + + /* encode the attribute dataspace */ + if((H5O_SDSPACE[0].encode)(f,p,&(attr->ds->u.simple))<0) { + HRETURN_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, + "can't encode attribute dataspace"); + } + p+=attr->ds_size; + + /* Store attribute data */ + HDmemcpy(p,attr->data,attr->data_size); + + FUNC_LEAVE(SUCCEED); +} + +/*-------------------------------------------------------------------------- + NAME + H5O_attr_copy + PURPOSE + Copies a message from MESG to DEST, allocating DEST if necessary. + USAGE + void *H5O_attr_copy(mesg, dest) + const void *mesg; IN: Pointer to the source attribute struct + const void *dest; IN: Pointer to the destination attribute struct + RETURNS + Pointer to DEST on success, NULL on failure + DESCRIPTION + This function copies a native (memory) attribute message, + allocating the destination structure if necessary. +--------------------------------------------------------------------------*/ +static void * +H5O_attr_copy(const void *_src, void *_dst) +{ + const H5A_t *src = (const H5A_t *) _src; + H5A_t *dst = NULL; + + FUNC_ENTER(H5O_attr_copy, NULL); + + /* check args */ + assert(src); + + /* copy */ + if (NULL == (dst = H5A_copy(src))) { + HRETURN_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "can't copy attribute"); + } + /* was result already allocated? */ + if (_dst) { + *((H5A_t *) _dst) = *dst; + H5MM_xfree(dst); + dst = (H5A_t *) _dst; + } + FUNC_LEAVE((void *) dst); +} + +/*-------------------------------------------------------------------------- + NAME + H5O_attr_size + PURPOSE + Return the raw message size in bytes + USAGE + size_t H5O_attr_size(f, mesg) + H5F_t *f; IN: pointer to the HDF5 file struct + const void *mesg; IN: Pointer to the source attribute struct + RETURNS + Size of message on success, 0 on failure + DESCRIPTION + This function returns the size of the raw attribute message on + success. (Not counting the message type or size fields, only the data + portion of the message). It doesn't take into account alignment. +--------------------------------------------------------------------------*/ +static size_t +H5O_attr_size(H5F_t __unused__ *f, const void *mesg) +{ + size_t ret_value = 0; + const H5A_t *attr = (const H5A_t *) mesg; + + FUNC_ENTER(H5O_attr_size, 0); + + assert(attr); + + /* Get size of name */ + ret_value=2; /* Size to store length of name */ + ret_value+=HDstrlen(attr->name); /* Add length of name (non-zero terminated) */ + + /* Get size of datatype information */ + ret_value+=attr->dt_size; + + /* Get size of [simple] dataspace information */ + ret_value+=attr->ds_size; + + /* Get size of attribute data */ + ret_value+=attr->data_size; + + FUNC_LEAVE(ret_value); +} + +/*------------------------------------------------------------------------- + * Function: H5O_attr_reset + * + * Purpose: Frees resources within a attribute message, but doesn't free + * the message itself. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, December 9, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_attr_reset(void *_mesg) +{ + H5A_t *attr = (H5A_t *) _mesg; + H5A_t *tmp = NULL; + + FUNC_ENTER(H5O_attr_reset, FAIL); + + if (attr) { + tmp = H5MM_xmalloc(sizeof(H5A_t)); + *tmp = *attr; + H5A_close(tmp); + HDmemset(attr, 0, sizeof(H5A_t)); + } + FUNC_LEAVE(SUCCEED); +} + +/*-------------------------------------------------------------------------- + NAME + H5O_attr_debug + PURPOSE + Prints debugging information for an attribute message + USAGE + void *H5O_attr_debug(f, mesg, stream, indent, fwidth) + H5F_t *f; IN: pointer to the HDF5 file struct + const void *mesg; IN: Pointer to the source attribute struct + FILE *stream; IN: Pointer to the stream for output data + intn indent; IN: Amount to indent information by + intn fwidth; IN: Field width (?) + RETURNS + SUCCEED/FAIL + DESCRIPTION + This function prints debugging output to the stream passed as a + parameter. +--------------------------------------------------------------------------*/ +static herr_t +H5O_attr_debug(H5F_t __unused__ *f, const void __unused__ *mesg, FILE __unused__ * stream, + intn __unused__ indent, intn __unused__ fwidth) +{ + const H5A_t *attr = (const H5A_t *) mesg; +#ifdef LATER + const char *s; + char buf[256]; + intn i, j; +#endif /* LATER */ + + FUNC_ENTER(H5O_attr_debug, FAIL); + + /* check args */ + assert(f); + assert(attr); + assert(stream); + assert(indent >= 0); + assert(fwidth >= 0); + +#ifdef LATER + switch (dt->type) { + case H5T_INTEGER: + s = "integer"; + break; + case H5T_FLOAT: + s = "floating-point"; + break; + case H5T_TIME: + s = "date and time"; + break; + case H5T_STRING: + s = "text string"; + break; + case H5T_BITFIELD: + s = "bit field"; + break; + case H5T_OPAQUE: + s = "opaque"; + break; + case H5T_COMPOUND: + s = "compound"; + break; + default: + sprintf(buf, "H5T_CLASS_%d", (int) (dt->type)); + s = buf; + break; + } + fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Type class:", + s); + + fprintf(stream, "%*s%-*s %lu byte%s\n", indent, "", fwidth, + "Size:", + (unsigned long) (dt->size), 1 == dt->size ? "" : "s"); + + if (H5T_COMPOUND == dt->type) { + fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth, + "Number of members:", + dt->u.compnd.nmembs); + for (i = 0; i < dt->u.compnd.nmembs; i++) { + sprintf(buf, "Member %d:", i); + fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + buf, + dt->u.compnd.memb[i].name); + fprintf(stream, "%*s%-*s %lu\n", indent + 3, "", MAX(0, fwidth-3), + "Byte offset:", + (unsigned long) (dt->u.compnd.memb[i].offset)); + fprintf(stream, "%*s%-*s %d%s\n", indent + 3, "", MAX(0, fwidth-3), + "Dimensionality:", + dt->u.compnd.memb[i].ndims, + 0 == dt->u.compnd.memb[i].ndims ? " (scalar)" : ""); + if (dt->u.compnd.memb[i].ndims > 0) { + fprintf(stream, "%*s%-*s {", indent + 3, "", MAX(0, fwidth-3), + "Size:"); + for (j = 0; j < dt->u.compnd.memb[i].ndims; j++) { + fprintf(stream, "%s%lu", j ? ", " : "", + (unsigned long) (dt->u.compnd.memb[i].dim[j])); + } + fprintf(stream, "}\n"); + fprintf(stream, "%*s%-*s {", indent + 3, "", MAX(0, fwidth-3), + "Permutation:"); + for (j = 0; j < dt->u.compnd.memb[i].ndims; j++) { + fprintf(stream, "%s%lu", j ? ", " : "", + (unsigned long) (dt->u.compnd.memb[i].perm[j])); + } + fprintf(stream, "}\n"); + } + H5O_dtype_debug(f, dt->u.compnd.memb[i].type, stream, + indent + 3, MAX(0, fwidth - 3)); + } + } else { + switch (dt->u.atomic.order) { + case H5T_ORDER_LE: + s = "little endian"; + break; + case H5T_ORDER_BE: + s = "big endian"; + break; + case H5T_ORDER_VAX: + s = "VAX"; + break; + case H5T_ORDER_NONE: + s = "none"; + break; + default: + sprintf(buf, "H5T_ORDER_%d", dt->u.atomic.order); + s = buf; + break; + } + fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Byte order:", + s); + + fprintf(stream, "%*s%-*s %lu bit%s\n", indent, "", fwidth, + "Precision:", + (unsigned long) (dt->u.atomic.prec), + 1 == dt->u.atomic.prec ? "" : "s"); + + fprintf(stream, "%*s%-*s %lu bit%s\n", indent, "", fwidth, + "Offset:", + (unsigned long) (dt->u.atomic.offset), + 1 == dt->u.atomic.offset ? "" : "s"); + + switch (dt->u.atomic.lsb_pad) { + case H5T_PAD_ZERO: + s = "zero"; + break; + case H5T_PAD_ONE: + s = "one"; + break; + default: + s = "pad?"; + break; + } + fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Low pad type:", s); + + switch (dt->u.atomic.msb_pad) { + case H5T_PAD_ZERO: + s = "zero"; + break; + case H5T_PAD_ONE: + s = "one"; + break; + default: + s = "pad?"; + break; + } + fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "High pad type:", s); + + if (H5T_FLOAT == dt->type) { + switch (dt->u.atomic.u.f.pad) { + case H5T_PAD_ZERO: + s = "zero"; + break; + case H5T_PAD_ONE: + s = "one"; + break; + default: + if (dt->u.atomic.u.f.pad < 0) { + sprintf(buf, "H5T_PAD_%d", -(dt->u.atomic.u.f.pad)); + } else { + sprintf(buf, "bit-%d", dt->u.atomic.u.f.pad); + } + s = buf; + break; + } + fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Internal pad type:", s); + + switch (dt->u.atomic.u.f.norm) { + case H5T_NORM_IMPLIED: + s = "implied"; + break; + case H5T_NORM_MSBSET: + s = "msb set"; + break; + case H5T_NORM_NONE: + s = "none"; + break; + default: + sprintf(buf, "H5T_NORM_%d", (int) (dt->u.atomic.u.f.norm)); + s = buf; + } + fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Normalization:", s); + + fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, + "Sign bit location:", + (unsigned long) (dt->u.atomic.u.f.sign)); + + fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, + "Exponent location:", + (unsigned long) (dt->u.atomic.u.f.epos)); + + fprintf(stream, "%*s%-*s 0x%08lx\n", indent, "", fwidth, + "Exponent bias:", + (unsigned long) (dt->u.atomic.u.f.ebias)); + + fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, + "Exponent size:", + (unsigned long) (dt->u.atomic.u.f.esize)); + + fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, + "Mantissa location:", + (unsigned long) (dt->u.atomic.u.f.mpos)); + + fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, + "Mantissa size:", + (unsigned long) (dt->u.atomic.u.f.msize)); + + } else if (H5T_INTEGER == dt->type) { + switch (dt->u.atomic.u.i.sign) { + case H5T_SGN_NONE: + s = "none"; + break; + case H5T_SGN_2: + s = "2's comp"; + break; + default: + sprintf(buf, "H5T_SGN_%d", (int) (dt->u.atomic.u.i.sign)); + s = buf; + break; + } + fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Sign scheme:", s); + + } + } +#endif /* LATER */ + + FUNC_LEAVE(SUCCEED); +} + diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index bd4503e..b6e340b 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -180,6 +180,14 @@ typedef struct H5O_compress_t { } H5O_compress_t; /* + * Attribute Message. + */ +#define H5O_ATTR_ID 0x000C +extern const H5O_class_t H5O_ATTR[1]; + +/* operates on an H5A_t struct */ + +/* * Object name message. */ #define H5O_NAME_ID 0x000d diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index 12ae765..0073c9b 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -258,7 +258,7 @@ H5O_sdspace_size(H5F_t *f, const void *mesg) */ size_t ret_value = 8; - FUNC_ENTER(H5O_sim_dtype_size, 0); + FUNC_ENTER(H5O_sdspace_size, 0); /* add in the dimension sizes */ ret_value += sdim->rank * H5F_SIZEOF_SIZE (f); diff --git a/src/H5S.c b/src/H5S.c index 177b5dc..47a1ac4 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -238,9 +238,7 @@ H5S_close(H5S_t *ds) break; case H5S_SIMPLE: - H5MM_xfree(ds->u.simple.size); - H5MM_xfree(ds->u.simple.max); - H5MM_xfree(ds->u.simple.perm); + H5S_close_simple(&(ds->u.simple)); break; case H5S_COMPLEX: @@ -262,6 +260,37 @@ H5S_close(H5S_t *ds) } /*------------------------------------------------------------------------- + * Function: H5S_close_simple + * + * Purpose: Releases all memory associated with a simple data space. + * (but doesn't free the simple space itself) + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Friday, April 17, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_close_simple(H5S_simple_t *simple) +{ + FUNC_ENTER(H5S_close_simple, FAIL); + + assert(simple); + + H5MM_xfree(simple->size); + H5MM_xfree(simple->max); + H5MM_xfree(simple->perm); + + FUNC_LEAVE(SUCCEED); +} + +/*------------------------------------------------------------------------- * Function: H5Scopy * * Purpose: Copies a dataspace. diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 07f4108..a023f5d 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -108,6 +108,7 @@ typedef struct H5S_tconv_t { } H5S_conv_t; H5S_t *H5S_copy (const H5S_t *src); +herr_t H5S_close_simple (H5S_simple_t *simple); herr_t H5S_close (H5S_t *ds); hsize_t H5S_get_npoints (const H5S_t *ds); hsize_t H5S_get_npoints_max(const H5S_t *ds); diff --git a/src/H5T.c b/src/H5T.c index 3ffbdcc..1a7f911 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -3006,9 +3006,9 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member) /* Does the new member overlap any existing member ? */ for (i = 0; i < parent->u.compnd.nmembs; i++) { - if ((offset < parent->u.compnd.memb[i].offset && + if ((offset <= parent->u.compnd.memb[i].offset && offset + member->size > parent->u.compnd.memb[i].offset) || - (parent->u.compnd.memb[i].offset < offset && + (parent->u.compnd.memb[i].offset <= offset && parent->u.compnd.memb[i].offset + parent->u.compnd.memb[i].type->size > offset)) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index 4c1a680..1fc4477 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -20,7 +20,7 @@ #include #include -#define HOFFSET(S,M) ((size_t)((const char*)&S.M-(const char*)&S)) +#define HOFFSET(S,M) (offsetof(S,M)) #define HPOFFSET(P,M) ((size_t)((const char*)&(P->M)-(const char*)P)) /* These are the various classes of data types */ diff --git a/src/H5public.h b/src/H5public.h index 81bbe17..0f2aebf 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -18,6 +18,7 @@ #include /*from configure */ #include +#include #ifdef HAVE_PARALLEL # include # include diff --git a/src/Makefile.in b/src/Makefile.in index ca59511..cd18e59 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -16,12 +16,12 @@ PROGS=debug h5ls # Source and object files for the library (lexicographically)... PARALLEL_SRC=H5Fmpio.c -LIB_SRC=H5.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcore.c H5Ffamily.c \ - H5Fistore.c H5Flow.c H5Fsec2.c H5Fsplit.c H5Fstdio.c H5G.c H5Gent.c \ - H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c H5O.c H5Ocomp.c \ - H5Ocont.c H5Odtype.c H5Oefl.c H5Olayout.c H5Oname.c H5Onull.c \ - H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5S.c H5Ssimp.c H5T.c \ - H5Tconv.c H5Tinit.c H5V.c H5Z.c @PARALLEL_SRC@ +LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcore.c \ + H5Ffamily.c H5Fistore.c H5Flow.c H5Fsec2.c H5Fsplit.c H5Fstdio.c H5G.c \ + H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c \ + H5O.c H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c H5Olayout.c \ + H5Oname.c H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5S.c \ + H5Ssimp.c H5T.c H5Tconv.c H5Tinit.c H5V.c H5Z.c @PARALLEL_SRC@ LIB_OBJ=$(LIB_SRC:.c=.o) @@ -33,16 +33,17 @@ PROG_SRC=debug.c h5ls.c PROG_OBJ=$(PROG_SRC:.c=.o) # Public header files (to be installed)... -PUB_HDR=H5public.h H5ACpublic.h H5Bpublic.h H5Ppublic.h H5Dpublic.h \ - H5Epublic.h H5Fpublic.h H5Gpublic.h H5HGpublic.h H5HLpublic.h \ - H5Ipublic.h H5MFpublic.h H5MMpublic.h H5Opublic.h H5Spublic.h \ - H5Tpublic.h H5Zpublic.h H5config.h hdf5.h +PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Ppublic.h \ + H5Dpublic.h H5Epublic.h H5Fpublic.h H5Gpublic.h H5HGpublic.h H5HLpublic.h \ + H5Ipublic.h H5MFpublic.h H5MMpublic.h H5Opublic.h H5Spublic.h \ + H5Tpublic.h H5config.h hdf5.h # Other header files (not to be installed)... -PRIVATE_HDR=H5private.h H5ACprivate.h H5Bprivate.h H5Pprivate.h H5Dprivate.h \ - H5Eprivate.h H5Fprivate.h H5Gprivate.h H5Gpkg.h H5HGprivate.h \ - H5HLprivate.h H5Iprivate.h H5MFprivate.h H5MMprivate.h H5Oprivate.h \ - H5Sprivate.h H5Tprivate.h H5Tpkg.h H5Vprivate.h H5Zprivate.h +PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \ + H5Pprivate.h H5Dprivate.h H5Dpkg.h H5Eprivate.h H5Fprivate.h H5Gprivate.h \ + H5Gpkg.h H5HGprivate.h H5HLprivate.h H5Iprivate.h H5MFprivate.h \ + H5MMprivate.h H5Oprivate.h H5Sprivate.h H5Tprivate.h H5Tpkg.h H5Vprivate.h \ + H5Zprivate.h # Number format detection H5Tinit.c: H5detect diff --git a/src/hdf5.h b/src/hdf5.h index ce4ed62..a80945b 100644 --- a/src/hdf5.h +++ b/src/hdf5.h @@ -19,6 +19,8 @@ #define _HDF5_H #include +#include /* IDs (this has to come near the top, to define hid_t) */ +#include /* Attributes */ #include /* Metadata cache */ #include /* B-trees */ #include /* Datasets */ @@ -27,7 +29,6 @@ #include /* Groups */ #include /* Global heaps */ #include /* Local heaps */ -#include /* IDs */ #include /* File memory management */ #include /* Core memory management */ #include /* Object headers */ -- cgit v0.12