summaryrefslogtreecommitdiffstats
path: root/src/H5A.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2015-05-15 01:33:12 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2015-05-15 01:33:12 (GMT)
commit3d5e75b0930bc87589727ce941e3e1f79a36bf20 (patch)
treefed45a49ba7dd2078604973738fbdabe4ee259a4 /src/H5A.c
parente81f0ade7781aec1960d50202fb838e300da0f96 (diff)
downloadhdf5-3d5e75b0930bc87589727ce941e3e1f79a36bf20.zip
hdf5-3d5e75b0930bc87589727ce941e3e1f79a36bf20.tar.gz
hdf5-3d5e75b0930bc87589727ce941e3e1f79a36bf20.tar.bz2
[svn-r27068] Description:
Clean up the H5A interface code, to better align with v3 metadata cache changes. Tested on: MacOSX/64 10.10.3 (amazon) w/serial & parallel Linux/32 2.6.x (jam) w/serial & parallel
Diffstat (limited to 'src/H5A.c')
-rw-r--r--src/H5A.c292
1 files changed, 279 insertions, 13 deletions
diff --git a/src/H5A.c b/src/H5A.c
index d474234..3b993ec 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -21,7 +21,7 @@
#define H5O_PACKAGE /*suppress error about including H5Opkg */
/* Interface initialization */
-#define H5_INTERFACE_INIT_FUNC H5A_init_interface
+#define H5_INTERFACE_INIT_FUNC H5A__init_interface
/***********/
@@ -63,6 +63,9 @@ typedef struct H5A_iter_cb1 {
/* Local Prototypes */
/********************/
+static herr_t H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id);
+static herr_t H5A__read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id);
+static ssize_t H5A__get_name(H5A_t *attr, size_t buf_size, char *buf);
/*********************/
/* Package Variables */
@@ -125,9 +128,9 @@ done:
/*--------------------------------------------------------------------------
NAME
- H5A_init_interface -- Initialize interface-specific information
+ H5A__init_interface -- Initialize interface-specific information
USAGE
- herr_t H5A_init_interface()
+ herr_t H5A__init_interface()
RETURNS
Non-negative on success/Negative on failure
@@ -136,11 +139,11 @@ DESCRIPTION
--------------------------------------------------------------------------*/
static herr_t
-H5A_init_interface(void)
+H5A__init_interface(void)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
/*
* Create attribute ID type.
@@ -150,7 +153,7 @@ H5A_init_interface(void)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5A_init_interface() */
+} /* end H5A__init_interface() */
/*--------------------------------------------------------------------------
@@ -407,7 +410,7 @@ H5Aopen(hid_t loc_id, const char *attr_name, hid_t UNUSED aapl_id)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to load attribute info from object header for attribute: '%s'", attr_name)
/* Finish initializing attribute */
- if(H5A_open_common(&loc, attr) < 0)
+ if(H5A__open_common(&loc, attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize attribute")
/* Register the attribute and get an ID for it */
@@ -595,7 +598,7 @@ H5Awrite(hid_t attr_id, hid_t dtype_id, const void *buf)
HGOTO_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, H5AC_dxpl_id)) < 0)
+ if((ret_value = H5A__write(attr, mem_type, buf, H5AC_dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute")
done:
@@ -605,6 +608,120 @@ done:
/*--------------------------------------------------------------------------
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
+ const void *buf; IN: Buffer of data to write
+ RETURNS
+ Non-negative on success/Negative on failure
+
+ DESCRIPTION
+ This function writes a complete attribute to disk.
+--------------------------------------------------------------------------*/
+static herr_t
+H5A__write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
+{
+ uint8_t *tconv_buf = NULL; /* datatype conv buffer */
+ hbool_t tconv_owned = FALSE; /* Whether the datatype conv buffer is owned by attribute */
+ uint8_t *bkg_buf = NULL; /* temp conversion buffer */
+ hssize_t snelmts; /* elements in attribute */
+ size_t nelmts; /* elements in attribute */
+ H5T_path_t *tpath = NULL; /* conversion information*/
+ 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 = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, attr->oloc.addr, FAIL)
+
+ HDassert(attr);
+ HDassert(mem_type);
+ HDassert(buf);
+
+ /* Get # of elements for attribute's dataspace */
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
+ H5_CHECKED_ASSIGN(nelmts, size_t, snelmts, hssize_t);
+
+ /* If there's actually data elements for the attribute, make a copy of the data passed in */
+ if(nelmts > 0) {
+ /* Get the memory and file datatype sizes */
+ src_type_size = H5T_GET_SIZE(mem_type);
+ dst_type_size = H5T_GET_SIZE(attr->shared->dt);
+
+ /* Convert memory buffer into disk buffer */
+ /* Set up type conversion function */
+ if(NULL == (tpath = H5T_path_find(mem_type, attr->shared->dt, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes")
+
+ /* Check for type conversion required */
+ if(!H5T_path_noop(tpath)) {
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0 ||
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
+
+ /* Get the maximum buffer size needed and allocate it */
+ buf_size = nelmts * MAX(src_type_size, dst_type_size);
+ if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed")
+ if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed")
+
+ /* Copy the user's data into the buffer for conversion */
+ HDmemcpy(tconv_buf, buf, (src_type_size * nelmts));
+
+ /* Perform datatype conversion */
+ if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed")
+
+ /* Free the previous attribute data buffer, if there is one */
+ if(attr->shared->data)
+ attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data);
+
+ /* Set the pointer to the attribute data to the converted information */
+ attr->shared->data = tconv_buf;
+ tconv_owned = TRUE;
+ } /* end if */
+ /* No type conversion necessary */
+ else {
+ HDassert(dst_type_size == src_type_size);
+
+ /* Allocate the attribute buffer, if there isn't one */
+ if(attr->shared->data == NULL)
+ if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size * nelmts)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Copy the attribute data into the user's buffer */
+ HDmemcpy(attr->shared->data, buf, (dst_type_size * nelmts));
+ } /* end else */
+
+ /* Modify the attribute in the object header */
+ if(H5O_attr_write(&(attr->oloc), dxpl_id, attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to modify attribute")
+ } /* end if */
+
+done:
+ /* Release resources */
+ if(src_id >= 0 && H5I_dec_ref(src_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object")
+ if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object")
+ if(tconv_buf && !tconv_owned)
+ tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf);
+ if(bkg_buf)
+ bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf);
+
+ FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
+} /* H5A__write() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5Aread
PURPOSE
Read in data from an attribute
@@ -638,7 +755,7 @@ H5Aread(hid_t attr_id, hid_t dtype_id, void *buf)
HGOTO_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, H5AC_ind_dxpl_id)) < 0)
+ if((ret_value = H5A__read(attr, mem_type, buf, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute")
done:
@@ -648,6 +765,109 @@ done:
/*--------------------------------------------------------------------------
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
+ Non-negative on success/Negative on failure
+
+ DESCRIPTION
+ This function reads a complete attribute from disk.
+--------------------------------------------------------------------------*/
+static herr_t
+H5A__read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
+{
+ uint8_t *tconv_buf = NULL; /* datatype conv buffer*/
+ uint8_t *bkg_buf = NULL; /* background buffer */
+ hssize_t snelmts; /* elements in attribute */
+ size_t nelmts; /* elements in attribute*/
+ H5T_path_t *tpath = NULL; /* type conversion info */
+ 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 = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(attr);
+ HDassert(mem_type);
+ HDassert(buf);
+
+ /* Create buffer for data to store on disk */
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
+ H5_CHECKED_ASSIGN(nelmts, size_t, snelmts, hssize_t);
+
+ if(nelmts > 0) {
+ /* Get the memory and file datatype sizes */
+ src_type_size = H5T_GET_SIZE(attr->shared->dt);
+ dst_type_size = H5T_GET_SIZE(mem_type);
+
+ /* Check if the attribute has any data yet, if not, fill with zeroes */
+ if(attr->obj_opened && !attr->shared->data)
+ HDmemset(buf, 0, (dst_type_size * nelmts));
+ else { /* Attribute exists and has a value */
+ /* Convert memory buffer into disk buffer */
+ /* Set up type conversion function */
+ if(NULL == (tpath = H5T_path_find(attr->shared->dt, mem_type, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes")
+
+ /* Check for type conversion required */
+ if(!H5T_path_noop(tpath)) {
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0 ||
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
+
+ /* Get the maximum buffer size needed and allocate it */
+ buf_size = nelmts * MAX(src_type_size, dst_type_size);
+ if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Copy the attribute data into the buffer for conversion */
+ HDmemcpy(tconv_buf, attr->shared->data, (src_type_size * nelmts));
+
+ /* Perform datatype conversion. */
+ if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed")
+
+ /* Copy the converted data into the user's buffer */
+ HDmemcpy(buf, tconv_buf, (dst_type_size * nelmts));
+ } /* end if */
+ /* No type conversion necessary */
+ else {
+ HDassert(dst_type_size == src_type_size);
+
+ /* Copy the attribute data into the user's buffer */
+ HDmemcpy(buf, attr->shared->data, (dst_type_size * nelmts));
+ } /* end else */
+ } /* end else */
+ } /* end if */
+
+done:
+ /* Release resources */
+ if(src_id >= 0 && H5I_dec_ref(src_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object")
+ if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object")
+ if(tconv_buf)
+ tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf);
+ if(bkg_buf)
+ bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A__read() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5Aget_space
PURPOSE
Gets a copy of the dataspace for an attribute
@@ -799,7 +1019,7 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer")
/* Call private function in turn */
- if(0 > (ret_value = H5A_get_name(my_attr, buf_size, buf)))
+ if(0 > (ret_value = H5A__get_name(my_attr, buf_size, buf)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get attribute name")
done:
@@ -807,6 +1027,52 @@ done:
} /* H5Aget_name() */
+/*--------------------------------------------------------------------------
+ NAME
+ H5A__get_name
+ PURPOSE
+ Private function for H5Aget_name. Gets a copy of the name for an
+ attribute
+ RETURNS
+ This function returns the length of the attribute's name (which may be
+ longer than 'buf_size') on success or negative for failure.
+ 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.
+--------------------------------------------------------------------------*/
+static ssize_t
+H5A__get_name(H5A_t *attr, size_t buf_size, char *buf)
+{
+ size_t copy_len, nbytes;
+ ssize_t ret_value;
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* get the real attribute length */
+ nbytes = HDstrlen(attr->shared->name);
+ HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/
+
+ /* compute the string length which will fit into the user's buffer */
+ copy_len = MIN(buf_size - 1, nbytes);
+
+ /* Copy all/some of the name */
+ if(buf && copy_len > 0) {
+ HDmemcpy(buf, attr->shared->name, copy_len);
+
+ /* Terminate the string */
+ buf[copy_len]='\0';
+ } /* end if */
+
+ /* Set return value */
+ ret_value = (ssize_t)nbytes;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5A_get_name() */
+
+
/*-------------------------------------------------------------------------
* Function: H5Aget_name_by_idx
*
@@ -942,7 +1208,7 @@ H5Aget_info(hid_t attr_id, H5A_info_t *ainfo)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
/* Get the attribute information */
- if(H5A_get_info(attr, ainfo) < 0)
+ if(H5A__get_info(attr, ainfo) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
done:
@@ -996,7 +1262,7 @@ H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name,
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
/* Get the attribute information */
- if(H5A_get_info(attr, ainfo) < 0)
+ if(H5A__get_info(attr, ainfo) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
done:
@@ -1058,7 +1324,7 @@ H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type,
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
/* Get the attribute information */
- if(H5A_get_info(attr, ainfo) < 0)
+ if(H5A__get_info(attr, ainfo) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info")
done: