summaryrefslogtreecommitdiffstats
path: root/src/H5Rint.c
diff options
context:
space:
mode:
authorJerome Soumagne <jsoumagne@hdfgroup.org>2019-10-08 20:06:55 (GMT)
committerJerome Soumagne <jsoumagne@hdfgroup.org>2019-10-08 20:06:55 (GMT)
commit4c558700ab33934e7358483c5d20fea4823baf9e (patch)
tree4ff47fe527c87edaef7b83e564f9dfa1e643d6b1 /src/H5Rint.c
parente9f253c7567cf508a3d40b863dce6455f0c93fdb (diff)
parent9ed9762889fcd05dc230d6652b92fddc5ec880a4 (diff)
downloadhdf5-4c558700ab33934e7358483c5d20fea4823baf9e.zip
hdf5-4c558700ab33934e7358483c5d20fea4823baf9e.tar.gz
hdf5-4c558700ab33934e7358483c5d20fea4823baf9e.tar.bz2
Merge pull request #1931 in HDFFV/hdf5 from feature/references to develop
* commit '9ed9762889fcd05dc230d6652b92fddc5ec880a4': Update RELEASE.txt for reference changes Fix reference type comparison in h5dump Make wrappers, tests and tools use H5Treclaim() instead of H5Dvlen_reclaim() Add new H5R API that abstracts object, region and attribute reference types Remove ability to loc by ref from H5VL layer Add support for retrieving object name by token Add H5VL_OBJECT_GET_TYPE to get object type Add H5VL_MAX_TOKEN_SIZE and H5VL_token_t Adapt Jerome's "file info" H5VL 'get' query to retrieve container token info. Fix H5VL_blob_get to return size of blob Add 'blob' callbacks to VOL, along with a native implementation to store them in the global heap, and changed the VL datatype conversion code to use blobs.
Diffstat (limited to 'src/H5Rint.c')
-rw-r--r--src/H5Rint.c1856
1 files changed, 1414 insertions, 442 deletions
diff --git a/src/H5Rint.c b/src/H5Rint.c
index 07efae2..e33eecb 100644
--- a/src/H5Rint.c
+++ b/src/H5Rint.c
@@ -35,11 +35,73 @@
#include "H5Sprivate.h" /* Dataspaces */
#include "H5Tprivate.h" /* Datatypes */
-
/****************/
/* Local Macros */
/****************/
+#define H5R_MAX_STRING_LEN (1 << 16) /* Max encoded string length */
+
+/* Encode macro */
+#define H5R_ENCODE(func, val, buf, buf_size, actual, m) do {\
+ size_t __nalloc = buf_size; \
+ if(func(val, buf, &__nalloc) < 0) \
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, m) \
+ if(buf && buf_size >= __nalloc) { \
+ buf += __nalloc; \
+ buf_size -= __nalloc; \
+ } \
+ actual += __nalloc; \
+} while(0)
+
+#define H5R_ENCODE_VAR(func, var, size, buf, buf_size, actual, m) do { \
+ size_t __nalloc = buf_size; \
+ if(func(var, size, buf, &__nalloc) < 0) \
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, m) \
+ if(buf && buf_size >= __nalloc) { \
+ p += __nalloc; \
+ buf_size -= __nalloc; \
+ } \
+ actual += __nalloc; \
+} while(0)
+
+/* Decode macro */
+#define H5R_DECODE(func, val, buf, buf_size, actual, m) do {\
+ size_t __nbytes = buf_size; \
+ if(func(buf, &__nbytes, val) < 0) \
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, m) \
+ buf += __nbytes; \
+ buf_size -= __nbytes; \
+ actual += __nbytes; \
+} while(0)
+
+#define H5R_DECODE_VAR(func, var, size, buf, buf_size, actual, m) do { \
+ size_t __nbytes = buf_size; \
+ if(func(buf, &__nbytes, var, size) < 0) \
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, m) \
+ p += __nbytes; \
+ buf_size -= __nbytes; \
+ actual += __nbytes; \
+} while(0)
+
+/* Debug */
+//#define H5R_DEBUG
+#ifdef H5R_DEBUG
+#define H5R_LOG_DEBUG(...) do { \
+ HDfprintf(stdout, " # %s(): ", __func__); \
+ HDfprintf(stdout, __VA_ARGS__); \
+ HDfprintf(stdout, "\n"); \
+ HDfflush(stdout); \
+ } while (0)
+static const char *
+H5R__print_token(const H5VL_token_t token) {
+ static char string[64];
+ HDsnprintf(string, 64, "%zu", *(haddr_t *)token);
+ return string;
+}
+#else
+#define H5R_LOG_DEBUG(...) do { } while (0)
+#endif
+
/******************/
/* Local Typedefs */
/******************/
@@ -48,6 +110,13 @@
/* Local Prototypes */
/********************/
+static herr_t H5R__encode_obj_token(const H5VL_token_t *obj_token, size_t token_size, unsigned char *buf, size_t *nalloc);
+static herr_t H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes, H5VL_token_t *obj_token, uint8_t *token_size);
+static herr_t H5R__encode_region(H5S_t *space, unsigned char *buf, size_t *nalloc);
+static herr_t H5R__decode_region(const unsigned char *buf, size_t *nbytes, H5S_t **space_ptr);
+static herr_t H5R__encode_string(const char *string, unsigned char *buf, size_t *nalloc);
+static herr_t H5R__decode_string(const unsigned char *buf, size_t *nbytes, char **string_ptr);
+
/*********************/
/* Package Variables */
/*********************/
@@ -82,14 +151,15 @@ DESCRIPTION
herr_t
H5R__init_package(void)
{
- herr_t ret_value = SUCCEED; /* Return value */
-
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Mark "top" of interface as initialized */
H5R_top_package_initialize_s = TRUE;
- FUNC_LEAVE_NOAPI(ret_value)
+ /* Sanity check, if assert fails, H5R_REF_BUF_SIZE must be increased */
+ HDcompile_assert(sizeof(H5R_ref_priv_t) <= H5R_REF_BUF_SIZE);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5R__init_package() */
@@ -167,571 +237,1473 @@ H5R_term_package(void)
} /* end H5R_term_package() */
-/*--------------------------------------------------------------------------
- NAME
- H5R__create
- PURPOSE
- Creates a particular kind of reference for the user
- USAGE
- herr_t H5R__create(ref, loc, name, ref_type, space)
- void *ref; OUT: Reference created
- H5G_loc_t *loc; IN: File location used to locate object pointed to
- const char *name; IN: Name of object at location LOC_ID of object
- pointed to
- H5R_type_t ref_type; IN: Type of reference to create
- H5S_t *space; IN: Dataspace ID with selection, used for Dataset
- Region references.
+/*-------------------------------------------------------------------------
+ * Function: H5R__create_object
+ *
+ * Purpose: Creates an object reference.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__create_object(const H5VL_token_t *obj_token, size_t token_size,
+ H5R_ref_priv_t *ref)
+{
+ size_t encode_size;
+ herr_t ret_value = SUCCEED; /* Return value */
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- Creates a particular type of reference specified with REF_TYPE, in the
- space pointed to by REF. The LOC_ID and NAME are used to locate the object
- pointed to and the SPACE_ID is used to choose the region pointed to (for
- Dataset Region references).
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
+ FUNC_ENTER_PACKAGE
+
+ HDassert(ref);
+
+ /* Create new reference */
+ H5MM_memcpy(ref->ref.obj.token, obj_token, token_size);
+ ref->ref.obj.filename = NULL;
+ ref->loc_id = H5I_INVALID_HID;
+ ref->type = (uint8_t)H5R_OBJECT2;
+ ref->token_size = (uint8_t)token_size;
+
+ /* Cache encoding size (assume no external reference) */
+ if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to determine encoding size")
+ ref->encode_size = (uint32_t)encode_size;
+
+ H5R_LOG_DEBUG("Created object reference, %d, filename=%s, obj_addr=%s, encode size=%u",
+ (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token),
+ ref->encode_size);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__create_object() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__create_region
+ *
+ * Purpose: Creates a region reference.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
herr_t
-H5R__create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space)
+H5R__create_region(const H5VL_token_t *obj_token, size_t token_size,
+ H5S_t *space, H5R_ref_priv_t *ref)
{
- H5G_loc_t obj_loc; /* Group hier. location of object */
- H5G_name_t path; /* Object group hier. path */
- H5O_loc_t oloc; /* Object object location */
- hbool_t obj_found = FALSE; /* Object location found */
- herr_t ret_value = SUCCEED; /* Return value */
+ size_t encode_size;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
- HDassert(_ref);
- HDassert(loc);
- HDassert(name);
- HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE);
+ HDassert(space);
+ HDassert(ref);
- /* Set up object location to fill in */
- obj_loc.oloc = &oloc;
- obj_loc.path = &path;
- H5G_loc_reset(&obj_loc);
+ /* Create new reference */
+ H5MM_memcpy(ref->ref.obj.token, obj_token, token_size);
+ ref->ref.obj.filename = NULL;
+ if(NULL == (ref->ref.reg.space = H5S_copy(space, FALSE, TRUE)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy dataspace")
- /* Set the FAPL for the API context */
- H5CX_set_libver_bounds(loc->oloc->file);
+ ref->loc_id = H5I_INVALID_HID;
+ ref->type = (uint8_t)H5R_DATASET_REGION2;
+ ref->token_size = (uint8_t)token_size;
- /* Find the object */
- if(H5G_loc_find(loc, name, &obj_loc) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found")
- obj_found = TRUE;
+ /* Cache encoding size (assume no external reference) */
+ if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to determine encoding size")
+ ref->encode_size = (uint32_t)encode_size;
- switch (ref_type) {
- case H5R_OBJECT:
- {
- hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ H5R_LOG_DEBUG("Created region reference, %d, filename=%s, obj_addr=%s, encode size=%u",
+ (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token),
+ ref->encode_size);
- *ref = obj_loc.oloc->addr;
- break;
+done:
+ if(ret_value < 0) {
+ if(ref->ref.reg.space) {
+ H5S_close(ref->ref.reg.space);
+ ref->ref.reg.space = NULL;
}
+ }
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5R__create_region */
- case H5R_DATASET_REGION:
- {
- H5HG_t hobjid; /* Heap object ID */
- hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
- hssize_t buf_size; /* Size of buffer needed to serialize selection */
- uint8_t *p; /* Pointer to OID to store */
- uint8_t *buf; /* Buffer to store serialized selection in */
- unsigned heapid_found; /* Flag for non-zero heap ID found */
- unsigned u; /* local index */
-
- /* Set up information for dataset region */
-
- /* Return any previous heap block to the free list if we are
- * garbage collecting
- */
- if (H5F_GC_REF(loc->oloc->file)) {
- /* Check for an existing heap ID in the reference */
- for (u = 0, heapid_found = 0, p = (uint8_t *)ref; u < H5R_DSET_REG_REF_BUF_SIZE; u++)
- if (p[u] != 0) {
- heapid_found = 1;
- break;
- }
-
- if (heapid_found != 0) {
- /* Return heap block to free list */
- }
- }
-
- /* Zero the heap ID out, may leak heap space if user is re-using
- * reference and doesn't have garbage collection turned on
- */
- HDmemset(ref, 0, H5R_DSET_REG_REF_BUF_SIZE);
-
- /* Get the amount of space required to serialize the selection */
- if ((buf_size = H5S_SELECT_SERIAL_SIZE(space)) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection")
-
- /* Increase buffer size to allow for the dataset OID */
- buf_size += (hssize_t)sizeof(haddr_t);
-
- /* Allocate the space to store the serialized information */
- H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t);
- if (NULL == (buf = (uint8_t *)H5MM_malloc((size_t)buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
-
- /* Serialize information for dataset OID into heap buffer */
- p = (uint8_t *)buf;
- H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr);
-
- /* Serialize the selection into heap buffer */
- if (H5S_SELECT_SERIALIZE(space, &p) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection")
-
- /* Save the serialized buffer for later */
- H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t);
- if(H5HG_insert(loc->oloc->file, (size_t)buf_size, buf, &hobjid) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection")
-
- /* Serialize the heap ID and index for storage in the file */
- p = (uint8_t *)ref;
- H5F_addr_encode(loc->oloc->file, &p, hobjid.addr);
- UINT32ENCODE(p, hobjid.idx);
-
- /* Free the buffer we serialized data in */
- H5MM_xfree(buf);
- break;
- } /* end case H5R_DATASET_REGION */
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__create_attr
+ *
+ * Purpose: Creates an attribute reference.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__create_attr(const H5VL_token_t *obj_token, size_t token_size,
+ const char *attr_name, H5R_ref_priv_t *ref)
+{
+ size_t encode_size;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ HDassert(attr_name);
+ HDassert(ref);
+
+ /* Make sure that attribute name is not longer than supported encode size */
+ if(HDstrlen(attr_name) > H5R_MAX_STRING_LEN)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, FAIL, "attribute name too long (%d > %d)", (int)HDstrlen(attr_name), H5R_MAX_STRING_LEN)
+
+ /* Create new reference */
+ H5MM_memcpy(ref->ref.obj.token, obj_token, token_size);
+ ref->ref.obj.filename = NULL;
+ if(NULL == (ref->ref.attr.name = HDstrdup(attr_name)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy attribute name")
+
+ ref->loc_id = H5I_INVALID_HID;
+ ref->type = (uint8_t)H5R_ATTR;
+ ref->token_size = (uint8_t)token_size;
+
+ /* Cache encoding size (assume no external reference) */
+ if(H5R__encode(NULL, ref, NULL, &encode_size, 0) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "unable to determine encoding size")
+ ref->encode_size = (uint32_t)encode_size;
+
+ H5R_LOG_DEBUG("Created attribute reference, %d, filename=%s, obj_addr=%s, attr name=%s, encode size=%u",
+ (int)sizeof(H5R_ref_priv_t), ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token),
+ ref->ref.attr.name, ref->encode_size);
+done:
+ if(ret_value < 0)
+ ref->ref.attr.name = H5MM_xfree(ref->ref.attr.name);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5R__create_attr */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__destroy
+ *
+ * Purpose: Destroy reference.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__destroy(H5R_ref_priv_t *ref)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ HDassert(ref != NULL);
+
+ ref->ref.obj.filename = H5MM_xfree(ref->ref.obj.filename);
+
+ switch(ref->type) {
+ case H5R_OBJECT2:
+ break;
+ case H5R_DATASET_REGION2:
+ if(H5S_close(ref->ref.reg.space) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "Cannot close dataspace")
+ ref->ref.reg.space = NULL;
+ break;
+ case H5R_ATTR:
+ ref->ref.attr.name = H5MM_xfree(ref->ref.attr.name);
+ break;
+ case H5R_OBJECT1:
+ case H5R_DATASET_REGION1:
case H5R_BADTYPE:
case H5R_MAXTYPE:
+ HDassert("invalid reference type" && 0);
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)")
default:
HDassert("unknown reference type" && 0);
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
} /* end switch */
-done:
- if (obj_found)
- H5G_loc_free(&obj_loc);
+ /* Decrement refcount of attached loc_id */
+ if((ref->loc_id != H5I_INVALID_HID) && (H5I_dec_ref(ref->loc_id) < 0))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "decrementing location ID failed")
+done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5R__create() */
+} /* end H5R__destroy() */
-/*--------------------------------------------------------------------------
- NAME
- H5R__dereference
- PURPOSE
- Opens the HDF5 object referenced.
- USAGE
- hid_t H5R__dereference(ref, oapl_id, ref_type, ref)
- H5F_t *file; IN: File the object being dereferenced is within
- hid_t oapl_id; IN: Object access property list ID
- H5R_type_t ref_type; IN: Type of reference
- void *ref; IN: Reference to open.
+/*-------------------------------------------------------------------------
+ * Function: H5R__set_loc_id
+ *
+ * Purpose: Attach location ID to reference and increment location refcount.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__set_loc_id(H5R_ref_priv_t *ref, hid_t id, hbool_t inc_ref)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
- RETURNS
- Valid ID on success, Negative on failure
- DESCRIPTION
- Given a reference to some object, open that object and return an ID for
- that object.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- Currently only set up to work with references to datasets
- EXAMPLES
- REVISION LOG
- Raymond Lu
- 13 July 2011
- I added the OAPL_ID parameter for the object being referenced. It only
- supports dataset access property list currently.
-
- M. Scot Breitenfeld
- 3 March 2015
- Added a check for undefined reference pointer.
---------------------------------------------------------------------------*/
+ FUNC_ENTER_PACKAGE
+
+ HDassert(ref != NULL);
+ HDassert(id != H5I_INVALID_HID);
+
+ /* If a location ID was previously assigned, decrement refcount and assign new one */
+ if((ref->loc_id != H5I_INVALID_HID) && (H5I_dec_ref(ref->loc_id) < 0))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "decrementing location ID failed")
+ ref->loc_id = id;
+
+ /* Prevent location ID from being freed until reference is destroyed */
+ if(inc_ref && H5I_inc_ref(ref->loc_id, FALSE) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINC, FAIL, "incrementing location ID failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__set_loc_id() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__get_loc_id
+ *
+ * Purpose: Retrieve location ID attached to existing reference.
+ *
+ * Return: Valid ID on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
hid_t
-H5R__dereference(H5F_t *file, hid_t oapl_id, H5R_type_t ref_type, const void *_ref)
+H5R__get_loc_id(const H5R_ref_priv_t *ref)
{
- H5O_loc_t oloc; /* Object location */
- H5G_name_t path; /* Path of object */
- H5G_loc_t loc; /* Group location */
- unsigned rc; /* Reference count of object */
- H5O_type_t obj_type; /* Type of object */
hid_t ret_value = H5I_INVALID_HID; /* Return value */
+ FUNC_ENTER_PACKAGE_NOERR
+
+ HDassert(ref != NULL);
+
+ ret_value = ref->loc_id;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__get_loc_id() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__reopen_file
+ *
+ * Purpose: Re-open referenced file using file access property list.
+ *
+ * Return: Valid ID on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5R__reopen_file(H5R_ref_priv_t *ref, hid_t fapl_id)
+{
+ void *new_file = NULL;
+ H5VL_connector_prop_t connector_prop;
+ unsigned flags = H5F_ACC_RDWR; /* Must open file read-write to allow for object modifications */
+ H5P_genplist_t *plist;
+ hid_t ret_value = H5I_INVALID_HID;
+
FUNC_ENTER_PACKAGE
- HDassert(_ref);
- HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE);
- HDassert(file);
+ /* TODO add search path */
- /* Initialize the object location */
- H5O_loc_reset(&oloc);
- oloc.file = file;
+ /* Verify access property list and set up collective metadata if appropriate */
+ if(H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, TRUE) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info")
- switch (ref_type) {
- case H5R_OBJECT:
- {
- oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */
- if (!H5F_addr_defined(oloc.addr) || oloc.addr == 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "Undefined reference pointer")
- break;
- }
+ /* Get the VOL info from the fapl */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a file access property list")
+ if(H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL connector info")
- case H5R_DATASET_REGION:
- {
- H5HG_t hobjid; /* Heap object ID */
- uint8_t *buf; /* Buffer to store serialized selection in */
- const uint8_t *p; /* Pointer to OID to store */
+ /* Stash a copy of the "top-level" connector property, before any pass-through
+ * connectors modify or unwrap it.
+ */
+ if(H5CX_set_vol_connector_prop(&connector_prop) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set VOL connector info in API context")
- /* Get the heap ID for the dataset region */
- p = (const uint8_t *)_ref;
- H5F_addr_decode(oloc.file, &p, &(hobjid.addr));
- UINT32DECODE(p, hobjid.idx);
+ /* Open the file */
+ if(NULL == (new_file = H5VL_file_open(&connector_prop, H5R_REF_FILENAME(ref), flags, fapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to open file")
- if (!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "Undefined reference pointer")
+ /* Get an ID for the file */
+ if((ret_value = H5VL_register_using_vol_id(H5I_FILE, new_file, connector_prop.connector_id, TRUE)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize file handle")
- /* Get the dataset region from the heap (allocate inside routine) */
- if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL)))
- HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, H5I_INVALID_HID, "Unable to read dataset region information")
+ /* Attach loc_id to reference */
+ if(H5R__set_loc_id((H5R_ref_priv_t *)ref, ret_value, FALSE) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, H5I_INVALID_HID, "unable to attach location id to reference")
- /* Get the object oid for the dataset */
- p = buf;
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__reopen_file() */
- /* Free the buffer allocated in H5HG_read() */
- H5MM_xfree(buf);
- break;
- } /* end case H5R_DATASET_REGION */
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__get_type
+ *
+ * Purpose: Given a reference to some object, return the type of that reference.
+ *
+ * Return: Type of the reference
+ *
+ *-------------------------------------------------------------------------
+ */
+H5R_type_t
+H5R__get_type(const H5R_ref_priv_t *ref)
+{
+ H5R_type_t ret_value = H5R_BADTYPE;
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ HDassert(ref != NULL);
+ ret_value = ref->type;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__get_type() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__equal
+ *
+ * Purpose: Compare two references
+ *
+ * Return: TRUE if equal, FALSE if unequal, FAIL if error
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5R__equal(const H5R_ref_priv_t *ref1, const H5R_ref_priv_t *ref2)
+{
+ htri_t ret_value = TRUE;
+
+ FUNC_ENTER_PACKAGE
+ HDassert(ref1 != NULL);
+ HDassert(ref2 != NULL);
+
+ /* Compare reference types */
+ if(ref1->type != ref2->type)
+ HGOTO_DONE(FALSE);
+
+ /* Compare object addresses */
+ if(ref1->token_size != ref2->token_size)
+ HGOTO_DONE(FALSE);
+ if(0 != HDmemcmp(ref1->ref.obj.token, ref2->ref.obj.token, ref1->token_size))
+ HGOTO_DONE(FALSE);
+
+ /* Compare filenames */
+ if((ref1->ref.obj.filename && (NULL == ref2->ref.obj.filename))
+ || ((NULL == ref1->ref.obj.filename) && ref2->ref.obj.filename))
+ HGOTO_DONE(FALSE);
+ if(ref1->ref.obj.filename && ref1->ref.obj.filename
+ && (0 != HDstrcmp(ref1->ref.obj.filename, ref2->ref.obj.filename)))
+ HGOTO_DONE(FALSE);
+
+ switch(ref1->type) {
+ case H5R_OBJECT2:
+ break;
+ case H5R_DATASET_REGION2:
+ if((ret_value = H5S_extent_equal(ref1->ref.reg.space, ref2->ref.reg.space)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOMPARE, FAIL, "cannot compare dataspace extents")
+ break;
+ case H5R_ATTR:
+ HDassert(ref1->ref.attr.name && ref2->ref.attr.name);
+ if(0 != HDstrcmp(ref1->ref.attr.name, ref2->ref.attr.name))
+ HGOTO_DONE(FALSE);
+ break;
+ case H5R_OBJECT1:
+ case H5R_DATASET_REGION1:
case H5R_BADTYPE:
case H5R_MAXTYPE:
+ HDassert("invalid reference type" && 0);
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)")
default:
HDassert("unknown reference type" && 0);
- HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5I_INVALID_HID, "internal error (unknown reference type)")
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
} /* end switch */
- /* Get the # of links for object, and its type
- * (To check to make certain that this object hasn't been deleted
- * since the reference was created)
- */
- if(H5O_get_rc_and_type(&oloc, &rc, &obj_type) < 0 || 0 == rc)
- HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, H5I_INVALID_HID, "dereferencing deleted object")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__equal() */
- /* Construct a group location for opening the object */
- H5G_name_reset(&path);
- loc.oloc = &oloc;
- loc.path = &path;
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__copy
+ *
+ * Purpose: Copy a reference
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__copy(const H5R_ref_priv_t *src_ref, H5R_ref_priv_t *dst_ref)
+{
+ herr_t ret_value = SUCCEED;
- /* Open the object */
- switch (obj_type) {
- case H5O_TYPE_GROUP:
- {
- H5G_t *group; /* Pointer to group to open */
+ FUNC_ENTER_PACKAGE
- if(NULL == (group = H5G_open(&loc)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5I_INVALID_HID, "not found")
+ HDassert((src_ref != NULL) && (dst_ref != NULL));
- /* Create an atom for the group */
- if((ret_value = H5I_register(H5I_GROUP, group, TRUE)) < 0) {
- H5G_close(group);
- HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register group")
- }
+ H5MM_memcpy(dst_ref->ref.obj.token, src_ref->ref.obj.token, src_ref->token_size);
+ dst_ref->encode_size = src_ref->encode_size;
+ dst_ref->type = src_ref->type;
+ dst_ref->token_size = src_ref->token_size;
+ switch(src_ref->type) {
+ case H5R_OBJECT2:
break;
- }
-
- case H5O_TYPE_NAMED_DATATYPE:
- {
- H5T_t *type; /* Pointer to datatype to open */
-
- if(NULL == (type = H5T_open(&loc)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, H5I_INVALID_HID, "not found")
+ case H5R_DATASET_REGION2:
+ if(NULL == (dst_ref->ref.reg.space = H5S_copy(src_ref->ref.reg.space, FALSE, TRUE)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy dataspace")
+ break;
+ case H5R_ATTR:
+ if(NULL == (dst_ref->ref.attr.name = HDstrdup(src_ref->ref.attr.name)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy attribute name")
+ break;
+ case H5R_OBJECT1:
+ case H5R_DATASET_REGION1:
+ HDassert("invalid reference type" && 0);
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)")
+ case H5R_BADTYPE:
+ case H5R_MAXTYPE:
+ default:
+ HDassert("unknown reference type" && 0);
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
+ } /* end switch */
- /* Create an atom for the datatype */
- if((ret_value = H5I_register(H5I_DATATYPE, type, TRUE)) < 0) {
- H5T_close(type);
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register datatype")
- }
+ /* We only need to keep a copy of the filename if we don't have the loc_id */
+ if(src_ref->loc_id == H5I_INVALID_HID) {
+ HDassert(src_ref->ref.obj.filename);
- break;
- }
+ if(NULL == (dst_ref->ref.obj.filename = HDstrdup(src_ref->ref.obj.filename)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Cannot copy filename")
+ dst_ref->loc_id = H5I_INVALID_HID;
+ } else {
+ dst_ref->ref.obj.filename = NULL;
- case H5O_TYPE_DATASET:
- {
- H5D_t *dset; /* Pointer to dataset to open */
+ /* Set location ID and hold reference to it */
+ if(H5R__set_loc_id(dst_ref, src_ref->loc_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "cannot set reference location ID")
+ }
- /* Open the dataset */
- if(NULL == (dset = H5D_open(&loc, oapl_id)))
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, H5I_INVALID_HID, "not found")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__copy() */
- /* Create an atom for the dataset */
- if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0) {
- H5D_close(dset);
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register dataset")
- }
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__get_obj_token
+ *
+ * Purpose: Given a reference to some object, get the encoded object addr.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__get_obj_token(const H5R_ref_priv_t *ref, H5VL_token_t *obj_token,
+ size_t *token_size)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
- break;
- }
+ FUNC_ENTER_PACKAGE
- case H5O_TYPE_MAP:
- HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, H5I_INVALID_HID, "maps not supported in native VOL connector")
+ HDassert(ref != NULL);
+ HDassert(ref->token_size <= H5VL_MAX_TOKEN_SIZE);
- case H5O_TYPE_UNKNOWN:
- case H5O_TYPE_NTYPES:
- default:
- HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, H5I_INVALID_HID, "can't identify type of object referenced")
- } /* end switch */
+ if(obj_token) {
+ if(0 == ref->token_size)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "NULL token size")
+ H5MM_memcpy(obj_token, ref->ref.obj.token, ref->token_size);
+ }
+ if(token_size)
+ *token_size = ref->token_size;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5R__dereference() */
+} /* end H5R__get_obj_token() */
-/*--------------------------------------------------------------------------
- NAME
- H5R__get_region
- PURPOSE
- Retrieves a dataspace with the region pointed to selected.
- USAGE
- H5S_t *H5R__get_region(file, ref)
- H5F_t *file; IN: File the object being dereferenced is within
- void *ref; IN: Reference to open.
+/*-------------------------------------------------------------------------
+ * Function: H5R__set_obj_token
+ *
+ * Purpose: Given a reference to some object, set the encoded object addr.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__set_obj_token(H5R_ref_priv_t *ref, const H5VL_token_t *obj_token,
+ size_t token_size)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
- RETURNS
- Pointer to the dataspace on success, NULL on failure
- DESCRIPTION
- Given a reference to some object, creates a copy of the dataset pointed
- to's dataspace and defines a selection in the copy which is the region
- pointed to.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-H5S_t *
-H5R__get_region(H5F_t *file, const void *_ref)
+ FUNC_ENTER_PACKAGE_NOERR
+
+ HDassert(ref != NULL);
+ HDassert(obj_token);
+ HDassert(token_size);
+ HDassert(token_size <= H5VL_MAX_TOKEN_SIZE);
+
+ H5MM_memcpy(ref->ref.obj.token, obj_token, ref->token_size);
+ ref->token_size = token_size;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__set_obj_token() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__get_region
+ *
+ * Purpose: Given a reference to some object, creates a copy of the dataset
+ * pointed to's dataspace and defines a selection in the copy which is the
+ * region pointed to.
+ *
+ * Return: Pointer to the dataspace on success/NULL on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__get_region(const H5R_ref_priv_t *ref, H5S_t *space)
{
- H5O_loc_t oloc; /* Object location */
- const uint8_t *p; /* Pointer to OID to store */
- H5HG_t hobjid; /* Heap object ID */
- uint8_t *buf = NULL; /* Buffer to store serialized selection in */
- H5S_t *ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
- HDassert(_ref);
- HDassert(file);
+ HDassert(ref != NULL);
+ HDassert(ref->type == H5R_DATASET_REGION2);
+ HDassert(space);
- /* Initialize the object location */
- H5O_loc_reset(&oloc);
- oloc.file = file;
+ /* Copy reference selection to destination */
+ if(H5S_select_copy(space, ref->ref.reg.space, FALSE) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "unable to copy selection")
- /* Get the heap ID for the dataset region */
- p = (const uint8_t *)_ref;
- H5F_addr_decode(oloc.file, &p, &(hobjid.addr));
- UINT32DECODE(p, hobjid.idx);
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__get_region() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__get_file_name
+ *
+ * Purpose: Given a reference to some object, determine a file name of the
+ * object located into.
+ *
+ * Return: Non-negative length of the path on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5R__get_file_name(const H5R_ref_priv_t *ref, char *buf, size_t size)
+{
+ size_t copy_len;
+ ssize_t ret_value = -1; /* Return value */
- /* Get the dataset region from the heap (allocate inside routine) */
- if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL)))
- HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, NULL, "Unable to read dataset region information")
+ FUNC_ENTER_PACKAGE
- /* Get the object oid for the dataset */
- p = buf;
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ /* Check args */
+ HDassert(ref != NULL);
- /* Open and copy the dataset's dataspace */
- if(NULL == (ret_value = H5S_read(&oloc)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found")
+ /* Return if that reference has no filename set */
+ if(!ref->ref.obj.filename)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, (-1), "no filename available for that reference")
- /* Unserialize the selection */
- if(H5S_SELECT_DESERIALIZE(&ret_value, &p) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection")
+ /* Get the file name length */
+ copy_len = HDstrlen(ref->ref.obj.filename);
+ HDassert(copy_len <= H5R_MAX_STRING_LEN);
-done:
- /* Free the buffer allocated in H5HG_read() */
- if(buf)
- H5MM_xfree(buf);
+ /* Copy the file name */
+ if(buf) {
+ copy_len = MIN(copy_len, size - 1);
+ H5MM_memcpy(buf, ref->ref.obj.filename, copy_len);
+ buf[copy_len] = '\0';
+ }
+ ret_value = (ssize_t)(copy_len + 1);
+done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5R__get_region() */
+} /* end H5R__get_file_name() */
-/*--------------------------------------------------------------------------
- NAME
- H5R__get_obj_type
- PURPOSE
- Retrieves the type of object that an object reference points to
- USAGE
- H5O_type_t H5R__get_obj_type(file, ref_type, ref)
- H5F_t *file; IN: File the object being dereferenced is within
- H5R_type_t ref_type; IN: Type of reference to query
- void *ref; IN: Reference to query.
- H5O_type_t *obj_type; OUT: The type of the object, set on success
+/*-------------------------------------------------------------------------
+ * Function: H5R__get_attr_name
+ *
+ * Purpose: Given a reference to some attribute, determine its name.
+ *
+ * Return: Non-negative length of the path on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5R__get_attr_name(const H5R_ref_priv_t *ref, char *buf, size_t size)
+{
+ ssize_t ret_value = -1; /* Return value */
+ size_t attr_name_len; /* Length of the attribute name */
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- Given a reference to some object, this function returns the type of object
- pointed to.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Check args */
+ HDassert(ref != NULL);
+ HDassert(ref->type == H5R_ATTR);
+
+ /* Get the attribute name length */
+ attr_name_len = HDstrlen(ref->ref.attr.name);
+ HDassert(attr_name_len <= H5R_MAX_STRING_LEN);
+
+ /* Get the attribute name */
+ if(buf) {
+ size_t copy_len = MIN(attr_name_len, size - 1);
+ H5MM_memcpy(buf, ref->ref.attr.name, copy_len);
+ buf[copy_len] = '\0';
+ }
+
+ ret_value = (ssize_t)(attr_name_len + 1);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__get_attr_name() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__encode
+ *
+ * Purpose: Private function for H5Rencode.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
herr_t
-H5R__get_obj_type(H5F_t *file, H5R_type_t ref_type, const void *_ref,
- H5O_type_t *obj_type)
+H5R__encode(const char *filename, const H5R_ref_priv_t *ref, unsigned char *buf,
+ size_t *nalloc, unsigned flags)
{
- H5O_loc_t oloc; /* Object location */
- unsigned rc; /* Reference count of object */
- herr_t ret_value = SUCCEED; /* Return value */
+ uint8_t *p = (uint8_t *)buf;
+ size_t buf_size = 0, encode_size = 0;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
- HDassert(file);
- HDassert(_ref);
+ HDassert(ref);
+ HDassert(nalloc);
+
+ /**
+ * Encoding format:
+ * | Reference type (8 bits) | Flags (8 bits) | Token (token size)
+ * | |
+ * | |----> H5R_IS_EXTERNAL: File info
+ * |
+ * |----> H5R_DATASET_REGION2: Serialized selection
+ * |
+ * |----> H5R_ATTR: Attribute name len + name
+ *
+ */
+
+ /* Don't encode if buffer size isn't big enough or buffer is empty */
+ if(buf && *nalloc >= H5R_ENCODE_HEADER_SIZE) {
+ /* Encode the type of the reference */
+ *p++ = (uint8_t)ref->type;
+
+ /* Encode the flags */
+ *p++ = (uint8_t)flags;
- /* Initialize the symbol table entry */
- H5O_loc_reset(&oloc);
- oloc.file = file;
+ buf_size = *nalloc - H5R_ENCODE_HEADER_SIZE;
+ }
+ encode_size += H5R_ENCODE_HEADER_SIZE;
+
+ /* Encode object token */
+ H5R_ENCODE_VAR(H5R__encode_obj_token, &ref->ref.obj.token, ref->token_size,
+ p, buf_size, encode_size, "Cannot encode object address");
+
+ /**
+ * TODO Encode VOL info
+ * When we have a better way of storing blobs, we should add
+ * support for referencing files in external VOLs.
+ * There are currently multiple limitations:
+ * - avoid duplicating VOL info on each reference
+ * - must query terminal VOL connector to avoid passthrough confusion
+ */
+ if(flags & H5R_IS_EXTERNAL) {
+ /* Encode file name */
+ H5R_ENCODE(H5R__encode_string, filename, p, buf_size, encode_size,
+ "Cannot encode filename");
+ }
- switch (ref_type) {
- case H5R_OBJECT:
- {
- /* Get the object oid */
- oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */
+ switch(ref->type) {
+ case H5R_OBJECT2:
break;
- }
+ case H5R_DATASET_REGION2:
+ /* Encode dataspace */
+ H5R_ENCODE(H5R__encode_region, ref->ref.reg.space, p, buf_size,
+ encode_size, "Cannot encode region");
+ break;
+ case H5R_ATTR:
+ /* Encode attribute name */
+ H5R_ENCODE(H5R__encode_string, ref->ref.attr.name, p, buf_size,
+ encode_size, "Cannot encode attribute name");
+ break;
+ case H5R_OBJECT1:
+ case H5R_DATASET_REGION1:
+ case H5R_BADTYPE:
+ case H5R_MAXTYPE:
+ HDassert("invalid reference type" && 0);
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)")
+ default:
+ HDassert("unknown reference type" && 0);
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
+ } /* end switch */
+
+ *nalloc = encode_size;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__encode() */
- case H5R_DATASET_REGION:
- {
- H5HG_t hobjid; /* Heap object ID */
- const uint8_t *p; /* Pointer to reference to decode */
- uint8_t *buf; /* Buffer to store serialized selection in */
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__decode
+ *
+ * Purpose: Private function for H5Rdecode.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__decode(const unsigned char *buf, size_t *nbytes, H5R_ref_priv_t *ref)
+{
+ const uint8_t *p = (const uint8_t *)buf;
+ size_t buf_size = 0, decode_size = 0;
+ uint8_t flags;
+ herr_t ret_value = SUCCEED;
- /* Get the heap ID for the dataset region */
- p = (const uint8_t *)_ref;
- H5F_addr_decode(oloc.file, &p, &(hobjid.addr));
- UINT32DECODE(p, hobjid.idx);
+ FUNC_ENTER_PACKAGE
- /* Get the dataset region from the heap (allocate inside routine) */
- if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL)))
- HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information")
+ HDassert(buf);
+ HDassert(nbytes);
+ HDassert(ref);
+ buf_size = *nbytes;
- /* Get the object oid for the dataset */
- p = buf;
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ /* Don't decode if buffer size isn't big enough */
+ if(buf_size < H5R_ENCODE_HEADER_SIZE)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small")
- /* Free the buffer allocated in H5HG_read() */
- H5MM_xfree(buf);
+ /* Set new reference */
+ ref->type = (H5R_type_t)*p++;
+ if(ref->type <= H5R_BADTYPE || ref->type >= H5R_MAXTYPE)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type")
- break;
- }
+ /* Set flags */
+ flags = *p++;
+
+ buf_size -= H5R_ENCODE_HEADER_SIZE;
+ decode_size += H5R_ENCODE_HEADER_SIZE;
+ /* Decode object token */
+ H5R_DECODE_VAR(H5R__decode_obj_token, &ref->ref.obj.token, &ref->token_size,
+ p, buf_size, decode_size, "Cannot decode object address");
+
+ /* We do not need to store the filename if the reference is internal */
+ if(flags & H5R_IS_EXTERNAL) {
+ /* Decode file name */
+ H5R_DECODE(H5R__decode_string, &ref->ref.obj.filename, p, buf_size,
+ decode_size, "Cannot decode filename");
+ } else
+ ref->ref.obj.filename = NULL;
+
+ switch(ref->type) {
+ case H5R_OBJECT2:
+ break;
+ case H5R_DATASET_REGION2:
+ /* Decode dataspace */
+ H5R_DECODE(H5R__decode_region, &ref->ref.reg.space, p, buf_size,
+ decode_size, "Cannot decode region");
+ break;
+ case H5R_ATTR:
+ /* Decode attribute name */
+ H5R_DECODE(H5R__decode_string, &ref->ref.attr.name, p, buf_size,
+ decode_size, "Cannot decode attribute name");
+ break;
+ case H5R_OBJECT1:
+ case H5R_DATASET_REGION1:
case H5R_BADTYPE:
case H5R_MAXTYPE:
+ HDassert("invalid reference type" && 0);
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (invalid reference type)")
default:
HDassert("unknown reference type" && 0);
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
} /* end switch */
- /* Get the # of links for object, and its type */
- /* (To check to make certain that this object hasn't been deleted since the reference was created) */
- if(H5O_get_rc_and_type(&oloc, &rc, obj_type) < 0 || 0 == rc)
- HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object")
+ /* Set loc ID to invalid */
+ ref->loc_id = H5I_INVALID_HID;
+
+ /* Set encoding size */
+ ref->encode_size = decode_size;
+
+ H5R_LOG_DEBUG("Decoded reference, filename=%s, obj_addr=%s, encode size=%u",
+ ref->ref.obj.filename, H5R__print_token(ref->ref.obj.token),
+ ref->encode_size);
+
+ *nbytes = decode_size;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5R__get_obj_type() */
+} /* end H5R__decode() */
-/*--------------------------------------------------------------------------
- NAME
- H5R__get_name
- PURPOSE
- Internal routine to determine a name for the object referenced
- USAGE
- ssize_t H5R__get_name(f, ref_type, ref, name, size)
- H5F_t *f; IN: Pointer to the file that the reference is pointing
- into
- hid_t lapl_id; IN: LAPL to use for operation
- hid_t id; IN: Location ID given for reference
- H5R_type_t ref_type; IN: Type of reference
- void *_ref; IN: Reference to query.
- char *name; OUT: Buffer to place name of object referenced
- size_t size; IN: Size of name buffer
+/*-------------------------------------------------------------------------
+ * Function: H5R__encode_obj_token
+ *
+ * Purpose: Encode an object address.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5R__encode_obj_token(const H5VL_token_t *obj_token, size_t token_size,
+ unsigned char *buf, size_t *nalloc)
+{
+ herr_t ret_value = SUCCEED;
- RETURNS
- Non-negative length of the path on success, -1 on failure
- DESCRIPTION
- Given a reference to some object, determine a path to the object
- referenced in the file.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- This may not be the only path to that object.
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-ssize_t
-H5R__get_name(H5F_t *f, H5R_type_t ref_type, const void *_ref,
- char *name, size_t size)
+ FUNC_ENTER_STATIC_NOERR
+
+ HDassert(nalloc);
+
+ /* Don't encode if buffer size isn't big enough or buffer is empty */
+ if(buf && *nalloc >= token_size) {
+ uint8_t *p = (uint8_t *)buf;
+
+ /* Encode token size */
+ *p++ = (uint8_t)(token_size & 0xff);
+
+ /* Encode token */
+ H5MM_memcpy(p, obj_token, token_size);
+ }
+ *nalloc = token_size + H5_SIZEOF_UINT8_T;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__encode_obj_token() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__decode_obj_token
+ *
+ * Purpose: Decode an object address.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5R__decode_obj_token(const unsigned char *buf, size_t *nbytes,
+ H5VL_token_t *obj_token, uint8_t *token_size)
{
- H5O_loc_t oloc; /* Object location describing object for reference */
- ssize_t ret_value = -1; /* Return value */
+ const uint8_t *p = (const uint8_t *)buf;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(buf);
+ HDassert(nbytes);
+ HDassert(obj_token);
+ HDassert(token_size);
+
+ /* Don't decode if buffer size isn't big enough */
+ if(*nbytes < H5_SIZEOF_UINT8_T)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small")
+
+ /* Get token size */
+ *token_size = *p++;
+ if(*token_size > sizeof(H5VL_token_t))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Invalid token size (%u)", *token_size)
+
+ /* Decode token */
+ H5MM_memcpy(obj_token, p, *token_size);
+
+ *nbytes = *token_size + H5_SIZEOF_UINT8_T;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__decode_obj_token() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__encode_region
+ *
+ * Purpose: Encode a selection.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5R__encode_region(H5S_t *space, unsigned char *buf, size_t *nalloc)
+{
+ uint8_t *p = NULL; /* Pointer to data to store */
+ hssize_t buf_size = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(space);
+ HDassert(nalloc);
+
+ /* Get the amount of space required to serialize the selection */
+ if((buf_size = H5S_SELECT_SERIAL_SIZE(space)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "Cannot determine amount of space needed for serializing selection")
+
+ /* Don't encode if buffer size isn't big enough or buffer is empty */
+ if(buf && *nalloc >= ((size_t)buf_size + 2 * H5_SIZEOF_UINT32_T)) {
+ p = (uint8_t *)buf;
+ int rank;
+
+ /* Encode the size for safety check */
+ UINT32ENCODE(p, (uint32_t)buf_size);
+
+ /* Encode the extent rank */
+ if((rank = H5S_get_simple_extent_ndims(space)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't get extent rank for selection")
+ UINT32ENCODE(p, (uint32_t)rank);
+
+ /* Serialize the selection */
+ if(H5S_SELECT_SERIALIZE(space, (unsigned char **)&p) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "can't serialize selection")
+ }
+ *nalloc = (size_t)buf_size + 2 * H5_SIZEOF_UINT32_T;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__encode_region() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__decode_region
+ *
+ * Purpose: Decode a selection.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5R__decode_region(const unsigned char *buf, size_t *nbytes, H5S_t **space_ptr)
+{
+ const uint8_t *p = (const uint8_t *)buf;
+ size_t buf_size = 0;
+ unsigned rank;
+ H5S_t *space;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(buf);
+ HDassert(nbytes);
+ HDassert(space_ptr);
+
+ /* Don't decode if buffer size isn't big enough */
+ if(*nbytes < (2 * H5_SIZEOF_UINT32_T))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small")
+
+ /* Decode the selection size */
+ UINT32DECODE(p, buf_size);
+ buf_size += H5_SIZEOF_UINT32_T;
+
+ /* Decode the extent rank */
+ UINT32DECODE(p, rank);
+ buf_size += H5_SIZEOF_UINT32_T;
+
+ /* Don't decode if buffer size isn't big enough */
+ if(*nbytes < buf_size)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small")
+
+ /* Deserialize the selection (dataspaces need the extent rank information) */
+ if(NULL == (space = H5S_create(H5S_SIMPLE)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small")
+ if(H5S_set_extent_simple(space, rank, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "can't set extent rank for selection")
+ if(H5S_SELECT_DESERIALIZE(&space, &p) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "can't deserialize selection")
+
+ *nbytes = buf_size;
+ *space_ptr = space;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__decode_region() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__encode_string
+ *
+ * Purpose: Encode a string.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5R__encode_string(const char *string, unsigned char *buf, size_t *nalloc)
+{
+ size_t string_len, buf_size;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(string);
+ HDassert(nalloc);
+
+ /* Get the amount of space required to serialize the string */
+ string_len = HDstrlen(string);
+ if(string_len > H5R_MAX_STRING_LEN)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, FAIL, "string too long")
+
+ /* Compute buffer size, allow for the attribute name length and object address */
+ buf_size = string_len + sizeof(uint16_t);
+
+ if(buf && *nalloc >= buf_size) {
+ uint8_t *p = (uint8_t *)buf;
+ /* Serialize information for string length into the buffer */
+ UINT16ENCODE(p, string_len);
+ /* Copy the string into the buffer */
+ H5MM_memcpy(p, string, string_len);
+ }
+ *nalloc = buf_size;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__encode_string() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__decode_string
+ *
+ * Purpose: Decode a string.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5R__decode_string(const unsigned char *buf, size_t *nbytes, char **string_ptr)
+{
+ const uint8_t *p = (const uint8_t *)buf;
+ size_t string_len;
+ char *string = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(buf);
+ HDassert(nbytes);
+ HDassert(string_ptr);
+
+ /* Don't decode if buffer size isn't big enough */
+ if(*nbytes < sizeof(uint16_t))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small")
+
+ /* Get the string length */
+ UINT16DECODE(p, string_len);
+ HDassert(string_len <= H5R_MAX_STRING_LEN);
+
+ /* Allocate the string */
+ if(NULL == (string = H5MM_malloc(string_len + 1)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, FAIL, "Cannot allocate string")
+
+ /* Copy the string */
+ H5MM_memcpy(string, p, string_len);
+ string[string_len] = '\0';
+
+ *string_ptr = string;
+ *nbytes = sizeof(uint16_t) + string_len;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__decode_string() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__encode_heap
+ *
+ * Purpose: Encode data and insert into heap (native only).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__encode_heap(H5F_t *f, unsigned char *buf, size_t *nalloc,
+ const unsigned char *data, size_t data_size)
+{
+ size_t buf_size;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
- /* Check args */
HDassert(f);
- HDassert(_ref);
+ HDassert(nalloc);
- /* Initialize the object location */
- H5O_loc_reset(&oloc);
- oloc.file = f;
+ buf_size = H5HG_HEAP_ID_SIZE(f);
+ if(buf && *nalloc >= buf_size) {
+ H5HG_t hobjid;
+ uint8_t *p = (uint8_t *)buf;
- /* Get address for reference */
- switch (ref_type) {
- case H5R_OBJECT:
- {
- oloc.addr = *(const hobj_ref_t *)_ref;
- break;
- }
+ /* Write the reference information to disk (allocates space also) */
+ if(H5HG_insert(f, data_size, (void *)data, &hobjid) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to write reference information")
- case H5R_DATASET_REGION:
- {
- H5HG_t hobjid; /* Heap object ID */
- uint8_t *buf; /* Buffer to store serialized selection in */
- const uint8_t *p; /* Pointer to OID to store */
+ /* Encode the heap information */
+ H5F_addr_encode(f, &p, hobjid.addr);
+ UINT32ENCODE(p, hobjid.idx);
+ }
+ *nalloc = buf_size;
- /* Get the heap ID for the dataset region */
- p = (const uint8_t *)_ref;
- H5F_addr_decode(oloc.file, &p, &(hobjid.addr));
- UINT32DECODE(p, hobjid.idx);
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__encode_heap() */
- /* Get the dataset region from the heap (allocate inside routine) */
- if((buf = (uint8_t *)H5HG_read(oloc.file, &hobjid, NULL, NULL)) == NULL)
- HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, (-1), "Unable to read dataset region information")
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__decode_heap
+ *
+ * Purpose: Decode data inserted into heap (native only).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__decode_heap(H5F_t *f, const unsigned char *buf, size_t *nbytes,
+ unsigned char **data_ptr, size_t *data_size)
+{
+ const uint8_t *p = (const uint8_t *)buf;
+ H5HG_t hobjid;
+ size_t buf_size;
+ herr_t ret_value = SUCCEED;
- /* Get the object oid for the dataset */
- p = buf;
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ FUNC_ENTER_PACKAGE
- /* Free the buffer allocated in H5HG_read() */
- H5MM_xfree(buf);
+ HDassert(f);
+ HDassert(buf);
+ HDassert(nbytes);
+ HDassert(data_ptr);
+
+ buf_size = H5HG_HEAP_ID_SIZE(f);
+ /* Don't decode if buffer size isn't big enough */
+ if(*nbytes < buf_size)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small")
+
+ /* Get the heap information */
+ H5F_addr_decode(f, &p, &(hobjid.addr));
+ if(!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer")
+ UINT32DECODE(p, hobjid.idx);
- break;
- }
+ /* Read the information from disk */
+ if(NULL == (*data_ptr = (unsigned char *)H5HG_read(f, &hobjid, (void *)*data_ptr, data_size)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "Unable to read reference data")
- case H5R_BADTYPE:
- case H5R_MAXTYPE:
- default:
- HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, (-1), "internal error (unknown reference type)")
- } /* end switch */
+ *nbytes = buf_size;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__decode_heap() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__free_heap
+ *
+ * Purpose: Remove data previously inserted into heap (native only).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__free_heap(H5F_t *f, const unsigned char *buf, size_t nbytes)
+{
+ H5HG_t hobjid;
+ const uint8_t *p = (const uint8_t *)buf;
+ size_t buf_size;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ HDassert(f);
+ HDassert(buf);
+
+ buf_size = H5HG_HEAP_ID_SIZE(f);
+ /* Don't decode if buffer size isn't big enough */
+ if(nbytes < buf_size)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small")
+
+ /* Get the heap information */
+ H5F_addr_decode(f, &p, &(hobjid.addr));
+ if(!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer")
+ UINT32DECODE(p, hobjid.idx);
+
+ /* Free heap object */
+ if(hobjid.addr > 0) {
+ /* Free heap object */
+ if(H5HG_remove(f, &hobjid) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to remove heap object")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__free_heap() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__decode_addr_compat
+ *
+ * Purpose: Decode an object address. (native only)
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__decode_addr_compat(hid_t id, H5I_type_t type, H5R_type_t ref_type,
+ const unsigned char *buf, haddr_t *addr_ptr)
+{
+ hid_t file_id = H5I_INVALID_HID; /* File ID for region reference */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ if(ref_type == H5R_OBJECT1) {
+ size_t buf_size = H5R_OBJ_REF_BUF_SIZE;
+
+ /* Get object address */
+ if(H5R__decode_addr_obj_compat(buf, &buf_size, addr_ptr) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address")
+ } else {
+ void *vol_obj_file = NULL;
+ H5F_t *f = NULL;
+ size_t buf_size = H5R_DSET_REG_REF_BUF_SIZE;
+
+ /* Get the file for the object */
+ if((file_id = H5F_get_file_id(id, type, FALSE)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
+
+ /* Retrieve VOL object */
+ if(NULL == (vol_obj_file = H5VL_vol_object(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Retrieve file from VOL object */
+ if(NULL == (f = (H5F_t *)H5VL_object_data(vol_obj_file)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object")
+
+ /* Get object address */
+ if(H5R__decode_addr_region_compat(f, buf, &buf_size, addr_ptr, NULL) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address")
+ }
+
+done:
+ if(file_id != H5I_INVALID_HID && H5I_dec_ref(file_id) < 0)
+ HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file")
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__encode_addr_obj_compat
+ *
+ * Purpose: Encode an object address. (native only)
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__encode_addr_obj_compat(haddr_t addr, unsigned char *buf, size_t *nalloc)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ HDassert(nalloc);
+
+ /* Don't encode if buffer size isn't big enough or buffer is empty */
+ if(buf && *nalloc >= sizeof(addr))
+ H5MM_memcpy(buf, &addr, sizeof(addr));
+ *nalloc = sizeof(addr);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__encode_addr_obj_compat() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__decode_addr_obj_compat
+ *
+ * Purpose: Decode an object address. (native only)
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__decode_addr_obj_compat(const unsigned char *buf, size_t *nbytes,
+ haddr_t *addr_ptr)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ HDassert(buf);
+ HDassert(nbytes);
+ HDassert(addr_ptr);
+
+ /* Don't decode if buffer size isn't big enough */
+ if(*nbytes < sizeof(*addr_ptr))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Buffer size is too small")
- /* Get name, length, etc. */
- if((ret_value = H5G_get_name_by_addr(f, &oloc, name, size)) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, (-1), "can't determine name")
+ H5MM_memcpy(addr_ptr, buf, sizeof(*addr_ptr));
+
+ *nbytes = sizeof(*addr_ptr);
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5R__get_name() */
+} /* H5R__decode_addr_obj_compat() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__encode_addr_region_compat
+ *
+ * Purpose: Encode dataset selection and insert data into heap (native only).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__encode_addr_region_compat(H5F_t *f, haddr_t obj_addr, H5S_t *space,
+ unsigned char *buf, size_t *nalloc)
+{
+ size_t buf_size;
+ unsigned char *data = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ HDassert(f);
+ HDassert(space);
+ HDassert(nalloc);
+
+ /* Get required buffer size */
+ if(H5R__encode_heap(f, NULL, &buf_size, NULL, (size_t)0) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ if(buf && *nalloc >= buf_size) {
+ ssize_t data_size;
+ uint8_t *p;
+
+ /* Pass the correct encoding version for the selection depending on the
+ * file libver bounds, this is later retrieved in H5S hyper encode */
+ H5CX_set_libver_bounds(f);
+
+ /* Zero the heap ID out, may leak heap space if user is re-using
+ * reference and doesn't have garbage collection turned on
+ */
+ HDmemset(buf, 0, buf_size);
+
+ /* Get the amount of space required to serialize the selection */
+ if((data_size = H5S_SELECT_SERIAL_SIZE(space)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection")
+ /* Increase buffer size to allow for the dataset OID */
+ data_size += (hssize_t)sizeof(haddr_t);
+
+ /* Allocate the space to store the serialized information */
+ H5_CHECK_OVERFLOW(data_size, hssize_t, size_t);
+ if(NULL == (data = (uint8_t *)H5MM_malloc((size_t)data_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Serialize information for dataset OID into heap buffer */
+ p = (uint8_t *)data;
+ H5F_addr_encode(f, &p, obj_addr);
+
+ /* Serialize the selection into heap buffer */
+ if(H5S_SELECT_SERIALIZE(space, &p) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection")
+
+ /* Write to heap */
+ if(H5R__encode_heap(f, buf, nalloc, data, (size_t)data_size) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+ }
+ *nalloc = buf_size;
+
+done:
+ H5MM_free(data);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5R__encode_addr_region_compat() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5R__decode_obj_addr_compat
+ *
+ * Purpose: Decode dataset selection from data inserted into heap (native only).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5R__decode_addr_region_compat(H5F_t *f, const unsigned char *buf,
+ size_t *nbytes, haddr_t *obj_addr_ptr, H5S_t **space_ptr)
+{
+ unsigned char *data = NULL;
+ size_t data_size;
+ haddr_t obj_addr;
+ const uint8_t *p;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_PACKAGE
+
+ HDassert(f);
+ HDassert(buf);
+ HDassert(nbytes);
+
+ /* Read from heap */
+ if(H5R__decode_heap(f, buf, nbytes, &data, &data_size) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Get object address */
+ p = (const uint8_t *)data;
+ H5F_addr_decode(f, &p, &obj_addr);
+ if(!H5F_addr_defined(obj_addr) || obj_addr == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer")
+
+ if(space_ptr) {
+ H5O_loc_t oloc; /* Object location */
+ H5S_t *space = NULL;
+
+ /* Initialize the object location */
+ H5O_loc_reset(&oloc);
+ oloc.file = f;
+ oloc.addr = obj_addr;
+
+ /* Open and copy the dataset's dataspace */
+ if(NULL == (space = H5S_read(&oloc)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, FAIL, "not found")
+
+ /* Unserialize the selection */
+ if(H5S_SELECT_DESERIALIZE(&space, &p) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "can't deserialize selection")
+
+ *space_ptr = space;
+ }
+ if(obj_addr_ptr)
+ *obj_addr_ptr = obj_addr;
+
+done:
+ H5MM_free(data);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__decode_addr_region_compat() */