summaryrefslogtreecommitdiffstats
path: root/src/H5R.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5R.c')
-rw-r--r--src/H5R.c837
1 files changed, 510 insertions, 327 deletions
diff --git a/src/H5R.c b/src/H5R.c
index 9df3e9f..dfc6394 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -365,14 +365,14 @@ H5R_create_attr(H5G_loc_t *loc, const char *name, hid_t dxpl_id, const char *att
HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, NULL, "attribute name too long")
/* Compute buffer size, allow for the attribute name length and object's OID */
- buf_size = attr_name_len + 2 + sizeof(haddr_t);
+ buf_size = attr_name_len + sizeof(uint16_t) + sizeof(haddr_t);
/* Allocate the space to store the serialized information */
if(NULL == (ref = (struct href_t *)H5MM_malloc(sizeof(struct href_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Cannot allocate memory for reference")
- if (NULL == (ref->ref.serial.buf = H5MM_malloc((size_t) buf_size)))
+ if (NULL == (ref->ref.serial.buf = H5MM_malloc(buf_size)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "Cannot allocate buffer to serialize selection")
- ref->ref.serial.buf_size = (size_t) buf_size;
+ ref->ref.serial.buf_size = buf_size;
ref->ref_type = H5R_ATTR;
/* Serialize information for object's OID into buffer */
@@ -404,8 +404,8 @@ done:
/*-------------------------------------------------------------------------
* Function: H5R_create_ext_object
*
- * Purpose: Creates an external object reference. The LOC and NAME are used to locate
- * the object pointed to.
+ * Purpose: Creates an external object reference. The FILENAME and PATHNAME
+ * are used to locate the object pointed to.
*
* Return: Success: Reference created
* Failure: NULL
@@ -413,13 +413,10 @@ done:
*-------------------------------------------------------------------------
*/
href_t
-H5R_create_ext_object(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
+H5R_create_ext_object(const char *filename, const char *pathname)
{
- 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 */
size_t filename_len; /* Length of the file name */
+ size_t pathname_len; /* Length of the obj path name */
size_t buf_size; /* Size of buffer needed to serialize reference */
uint8_t *p; /* Pointer to OID to store */
struct href_t *ref = NULL; /* Reference to be returned */
@@ -427,30 +424,23 @@ H5R_create_ext_object(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
FUNC_ENTER_NOAPI_NOINIT
- HDassert(loc);
- HDassert(name);
-
- /* Set up object location to fill in */
- obj_loc.oloc = &oloc;
- obj_loc.path = &path;
- H5G_loc_reset(&obj_loc);
-
- /* Find the object */
- if(H5G_loc_find(loc, name, &obj_loc, H5P_DEFAULT, dxpl_id) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, NULL, "object not found")
- obj_found = TRUE;
+ HDassert(filename);
+ HDassert(pathname);
/* Need to add name of the file */
- filename_len = HDstrlen(H5F_OPEN_NAME(loc->oloc->file));
+ filename_len = HDstrlen(filename);
- /* Compute buffer size, allow for the attribute name length and object's OID */
- buf_size = filename_len + 2 + sizeof(haddr_t);
+ /* Need to add object path name */
+ pathname_len = HDstrlen(pathname);
+
+ /* Compute buffer size, allow for the file name and object path name lengths */
+ buf_size = filename_len + pathname_len + 2 * sizeof(uint16_t);
if(NULL == (ref = (struct href_t *)H5MM_malloc(sizeof(struct href_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Cannot allocate memory for reference")
- if (NULL == (ref->ref.serial.buf = H5MM_malloc((size_t) buf_size)))
+ if (NULL == (ref->ref.serial.buf = H5MM_malloc(buf_size)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "Cannot allocate buffer to serialize selection")
- ref->ref.serial.buf_size = (size_t) buf_size;
+ ref->ref.serial.buf_size = buf_size;
ref->ref_type = H5R_EXT_OBJECT;
/* Serialize information for file name length into the buffer */
@@ -458,17 +448,21 @@ H5R_create_ext_object(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
UINT16ENCODE(p, filename_len);
/* Copy the file name into the buffer */
- HDmemcpy(p, H5F_OPEN_NAME(loc->oloc->file), filename_len);
+ HDmemcpy(p, filename, filename_len);
p += filename_len;
- /* Serialize information for object's OID into buffer */
- H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr);
+ /* Serialize information for object path name length into the buffer */
+ UINT16ENCODE(p, pathname_len);
+
+ /* Copy the object path name into the buffer */
+ HDmemcpy(p, pathname, pathname_len);
+
+ /* Sanity check */
+ HDassert((size_t)((p + pathname_len) - (uint8_t *)ref->ref.serial.buf) == buf_size);
ret_value = ref;
done:
- if(obj_found)
- H5G_loc_free(&obj_loc);
if(NULL == ret_value) {
H5MM_free(ref->ref.serial.buf);
H5MM_free(ref);
@@ -480,8 +474,9 @@ done:
/*-------------------------------------------------------------------------
* Function: H5R_create_ext_region
*
- * Purpose: Creates an external region reference. The LOC and NAME are used to locate
- * the object pointed to and the SPACE is used to choose the region pointed to.
+ * Purpose: Creates an external region reference. The FILENAME and PATHNAME
+ * are used to locate the object pointed to and the SPACE is used to choose
+ * the region pointed to.
*
* Return: Success: Reference created
* Failure: NULL
@@ -489,51 +484,41 @@ done:
*-------------------------------------------------------------------------
*/
href_t
-H5R_create_ext_region(H5G_loc_t *loc, const char *name, hid_t dxpl_id, H5S_t *space)
+H5R_create_ext_region(const char *filename, const char *pathname, H5S_t *space)
{
- 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 */
size_t filename_len; /* Length of the file name */
- hssize_t buf_size; /* Size of buffer needed to serialize selection */
- uint8_t *p; /* Pointer to OID to store */
+ size_t pathname_len; /* Length of the obj path name */
+ size_t buf_size; /* Size of buffer needed to serialize selection */
+ size_t space_buf_size; /* Size of buffer needed to serialize selection */
+ uint8_t *p = NULL; /* Pointer to OID to store */
struct href_t *ref = NULL; /* Reference to be returned */
struct href_t *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
- HDassert(loc);
- HDassert(name);
+ HDassert(filename);
+ HDassert(pathname);
HDassert(space);
- /* Set up object location to fill in */
- obj_loc.oloc = &oloc;
- obj_loc.path = &path;
- H5G_loc_reset(&obj_loc);
-
- /* Find the object */
- if(H5G_loc_find(loc, name, &obj_loc, H5P_DEFAULT, dxpl_id) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, NULL, "object not found")
- obj_found = TRUE;
-
/* Need to add name of the file */
- filename_len = HDstrlen(H5F_OPEN_NAME(loc->oloc->file));
+ filename_len = HDstrlen(filename);
+
+ /* Need to add object path name */
+ pathname_len = HDstrlen(pathname);
/* 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, NULL, "Invalid amount of space for serializing selection")
+ if (H5S_encode(space, &p, &space_buf_size) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, NULL, "Unable to serialize selection")
- /* Increase buffer size to allow for the dataset OID */
- buf_size += (hssize_t)(sizeof(haddr_t) + 2 + filename_len);
+ /* Compute buffer size, allow for the file name and object path name lengths */
+ buf_size = space_buf_size + filename_len + pathname_len + 2 * sizeof(uint16_t);
/* Allocate the space to store the serialized information */
- H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t);
if(NULL == (ref = (struct href_t *)H5MM_malloc(sizeof(struct href_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Cannot allocate memory for reference")
if (NULL == (ref->ref.serial.buf = H5MM_malloc((size_t) buf_size)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "Cannot allocate buffer to serialize selection")
- ref->ref.serial.buf_size = (size_t) buf_size;
+ ref->ref.serial.buf_size = buf_size;
ref->ref_type = H5R_EXT_REGION;
/* Serialize information for file name length into the buffer */
@@ -541,21 +526,26 @@ H5R_create_ext_region(H5G_loc_t *loc, const char *name, hid_t dxpl_id, H5S_t *sp
UINT16ENCODE(p, filename_len);
/* Copy the file name into the buffer */
- HDmemcpy(p, H5F_OPEN_NAME(loc->oloc->file), filename_len);
+ HDmemcpy(p, filename, filename_len);
p += filename_len;
- /* Serialize information for dataset OID into buffer */
- H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr);
+ /* Serialize information for object path name length into the buffer */
+ UINT16ENCODE(p, pathname_len);
+
+ /* Copy the object path name into the buffer */
+ HDmemcpy(p, pathname, pathname_len);
+ p += pathname_len;
/* Serialize the selection into buffer */
- if(H5S_SELECT_SERIALIZE(space, &p) < 0)
+ if (H5S_encode(space, &p, &space_buf_size) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, NULL, "Unable to serialize selection")
+ /* Sanity check */
+ HDassert((size_t)(p - (uint8_t *)ref->ref.serial.buf) == (size_t)buf_size);
+
ret_value = ref;
done:
- if(obj_found)
- H5G_loc_free(&obj_loc);
if(NULL == ret_value) {
H5MM_free(ref->ref.serial.buf);
H5MM_free(ref);
@@ -567,8 +557,8 @@ done:
/*-------------------------------------------------------------------------
* Function: H5R_create_ext_attr
*
- * Purpose: Creates an external attribute reference. The LOC, NAME and ATTR_NAME are
- * used to locate the attribute pointed to.
+ * Purpose: Creates an external attribute reference. The FILENAME, PATHNAME
+ * and ATTR_NAME are used to locate the attribute pointed to.
*
* Return: Success: Reference created
* Failure: NULL
@@ -576,52 +566,42 @@ done:
*-------------------------------------------------------------------------
*/
href_t
-H5R_create_ext_attr(H5G_loc_t *loc, const char *name, hid_t dxpl_id, const char *attr_name)
+H5R_create_ext_attr(const char *filename, const char *pathname, const char *attr_name)
{
- 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 */
size_t filename_len; /* Length of the file name */
- size_t buf_size; /* Size of buffer needed to serialize attribute */
+ size_t pathname_len; /* Length of the obj path name */
size_t attr_name_len; /* Length of the attribute name */
+ size_t buf_size; /* Size of buffer needed to serialize reference */
uint8_t *p; /* Pointer to OID to store */
struct href_t *ref = NULL; /* Reference to be returned */
struct href_t *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
- HDassert(loc);
- HDassert(name);
+ HDassert(filename);
+ HDassert(pathname);
HDassert(attr_name);
- /* Set up object location to fill in */
- obj_loc.oloc = &oloc;
- obj_loc.path = &path;
- H5G_loc_reset(&obj_loc);
-
- /* Find the object */
- if(H5G_loc_find(loc, name, &obj_loc, H5P_DEFAULT, dxpl_id) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, NULL, "object not found")
- obj_found = TRUE;
-
/* Need to add name of the file */
- filename_len = HDstrlen(H5F_OPEN_NAME(loc->oloc->file));
+ filename_len = HDstrlen(filename);
+
+ /* Need to add object path name */
+ pathname_len = HDstrlen(pathname);
/* Get the amount of space required to serialize the attribute name */
attr_name_len = HDstrlen(attr_name);
if(attr_name_len >= H5R_MAX_ATTR_REF_NAME_LEN)
HGOTO_ERROR(H5E_REFERENCE, H5E_ARGS, NULL, "attribute name too long")
- /* Compute buffer size, allow for the attribute name length and object's OID */
- buf_size = filename_len + 2 + attr_name_len + 2 + sizeof(haddr_t);
+ /* Compute buffer size, allow for the file name and object path name lengths */
+ buf_size = filename_len + pathname_len + attr_name_len + 3 * sizeof(uint16_t);
/* Allocate the space to store the serialized information */
if(NULL == (ref = (struct href_t *)H5MM_malloc(sizeof(struct href_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Cannot allocate memory for reference")
- if (NULL == (ref->ref.serial.buf = H5MM_malloc((size_t) buf_size)))
+ if (NULL == (ref->ref.serial.buf = H5MM_malloc(buf_size)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "Cannot allocate buffer to serialize selection")
- ref->ref.serial.buf_size = (size_t) buf_size;
+ ref->ref.serial.buf_size = buf_size;
ref->ref_type = H5R_EXT_ATTR;
/* Serialize information for file name length into the buffer */
@@ -629,11 +609,15 @@ H5R_create_ext_attr(H5G_loc_t *loc, const char *name, hid_t dxpl_id, const char
UINT16ENCODE(p, filename_len);
/* Copy the file name into the buffer */
- HDmemcpy(p, H5F_OPEN_NAME(loc->oloc->file), filename_len);
+ HDmemcpy(p, filename, filename_len);
p += filename_len;
- /* Serialize information for object's OID into buffer */
- H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr);
+ /* Serialize information for object path name length into the buffer */
+ UINT16ENCODE(p, pathname_len);
+
+ /* Copy the object path name into the buffer */
+ HDmemcpy(p, pathname, pathname_len);
+ p += pathname_len;
/* Serialize information for attribute name length into the buffer */
UINT16ENCODE(p, attr_name_len);
@@ -647,8 +631,6 @@ H5R_create_ext_attr(H5G_loc_t *loc, const char *name, hid_t dxpl_id, const char
ret_value = ref;
done:
- if(obj_found)
- H5G_loc_free(&obj_loc);
if(NULL == ret_value) {
H5MM_free(ref->ref.serial.buf);
H5MM_free(ref);
@@ -764,8 +746,8 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Rcreate_ext_object
*
- * Purpose: Creates an external object reference. The LOC_ID and NAME are
- * used to locate the object pointed to.
+ * Purpose: Creates an external object reference. The FILENAME and PATHNAME
+ * are used to locate the object pointed to.
*
* Return: Success: Reference created
* Failure: NULL
@@ -773,20 +755,19 @@ done:
*-------------------------------------------------------------------------
*/
href_t
-H5Rcreate_ext_object(hid_t loc_id, const char *name)
+H5Rcreate_ext_object(const char *filename, const char *pathname)
{
- H5G_loc_t loc; /* File location */
href_t ret_value = NULL; /* Return value */
FUNC_ENTER_API(NULL)
/* Check args */
- if(H5G_loc(loc_id, &loc) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a location")
- if(!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no name given")
+ if(!filename || !*filename)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no filename given")
+ if(!pathname || !*pathname)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no pathname given")
- if(NULL == (ret_value = H5R_create_ext_object(&loc, name, H5AC_dxpl_id)))
+ if(NULL == (ret_value = H5R_create_ext_object(filename, pathname)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, NULL, "unable to create object reference")
done:
@@ -796,8 +777,8 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Rcreate_ext_region
*
- * Purpose: Creates an external region reference. The LOC_ID and NAME are
- * used to locate the object pointed to and the SPACE_ID is used to choose
+ * Purpose: Creates an external region reference. The FILENAME and PATHNAME
+ * are used to locate the object pointed to and the SPACE_ID is used to choose
* the region pointed to.
*
* Return: Success: Reference created
@@ -806,25 +787,24 @@ done:
*-------------------------------------------------------------------------
*/
href_t
-H5Rcreate_ext_region(hid_t loc_id, const char *name, hid_t space_id)
+H5Rcreate_ext_region(const char *filename, const char *pathname, hid_t space_id)
{
- H5G_loc_t loc; /* File location */
H5S_t *space = NULL; /* Pointer to dataspace containing region */
href_t ret_value = NULL; /* Return value */
FUNC_ENTER_API(NULL)
/* Check args */
- if(H5G_loc(loc_id, &loc) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a location")
- if(!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no name given")
+ if(!filename || !*filename)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no filename given")
+ if(!pathname || !*pathname)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no pathname given")
if(space_id == H5I_BADID)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "reference region dataspace id must be valid")
if(space_id != H5I_BADID && (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a dataspace")
- if(NULL == (ret_value = H5R_create_ext_region(&loc, name, H5AC_dxpl_id, space)))
+ if(NULL == (ret_value = H5R_create_ext_region(filename, pathname, space)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, NULL, "unable to create region reference")
done:
@@ -834,8 +814,8 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Rcreate_ext_attr
*
- * Purpose: Creates an external attribute reference. The LOC_ID, NAME and
- * ATTR_NAME are used to locate the attribute pointed to.
+ * Purpose: Creates an external attribute reference. The FILENAME, PATHNAME
+ * and ATTR_NAME are used to locate the attribute pointed to.
*
* Return: Success: Reference created
* Failure: NULL
@@ -843,22 +823,21 @@ done:
*-------------------------------------------------------------------------
*/
href_t
-H5Rcreate_ext_attr(hid_t loc_id, const char *name, const char *attr_name)
+H5Rcreate_ext_attr(const char *filename, const char *pathname, const char *attr_name)
{
- H5G_loc_t loc; /* File location */
href_t ret_value = NULL; /* Return value */
FUNC_ENTER_API(NULL)
/* Check args */
- if(H5G_loc(loc_id, &loc) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a location")
- if(!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no name given")
+ if(!filename || !*filename)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no filename given")
+ if(!pathname || !*pathname)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no pathname given")
if(!attr_name || !*attr_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no attribute name given")
- if(NULL == (ret_value = H5R_create_ext_attr(&loc, name, H5AC_dxpl_id, attr_name)))
+ if(NULL == (ret_value = H5R_create_ext_attr(filename, pathname, attr_name)))
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, NULL, "unable to create atribute reference")
done:
@@ -1049,7 +1028,7 @@ done:
} /* end H5Requal() */
/*-------------------------------------------------------------------------
- * Function: H5R__dereference
+ * Function: H5R__get_object
*
* Purpose: Given a reference to some object, open that object and return an
* ID for that object.
@@ -1059,14 +1038,15 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5R__dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, href_t _ref, hbool_t app_ref)
+H5R__get_object(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, href_t _ref, hbool_t app_ref)
{
H5O_loc_t oloc; /* Object location */
H5G_name_t path; /* Path of object */
H5G_loc_t loc; /* Group location */
- char *attr_name = NULL; /* Name of the attribute (for attribute references) */
+ char *pathname = NULL; /* Path name of the object (for external references) */
unsigned rc; /* Reference count of object */
H5O_type_t obj_type; /* Type of object */
+ hbool_t ext_ref = FALSE; /* External reference */
const uint8_t *p = NULL; /* Pointer to OID to store */
struct href_t *ref = (struct href_t *) _ref; /* Reference */
hid_t ret_value = H5I_BADID; /* Return value */
@@ -1081,176 +1061,159 @@ H5R__dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, href_t _ref, hbool_t
H5O_loc_reset(&oloc);
oloc.file = file;
+ /* Construct a group location for opening the object */
+ H5G_name_reset(&path);
+ loc.oloc = &oloc;
+ loc.path = &path;
+
+ /* Point to reference buffer now */
+ p = (const uint8_t *)ref->ref.serial.buf;
+
+ /* Decode reference */
switch (ref->ref_type) {
+ case H5R_OBJECT:
+ oloc.addr = ref->ref.addr;
+ if(!H5F_addr_defined(oloc.addr) || oloc.addr == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer")
+ break;
+ case H5R_REGION:
+ case H5R_ATTR:
+ /* Get the object oid for the dataset */
+ H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ break;
case H5R_EXT_OBJECT:
case H5R_EXT_REGION:
case H5R_EXT_ATTR:
{
size_t filename_len; /* Length of the file name */
+ size_t pathname_len; /* Length of the obj path name */
/* Get the file name length */
- p = (const uint8_t *)ref->ref.serial.buf;
UINT16DECODE(p, filename_len);
HDassert(filename_len < H5R_MAX_ATTR_REF_NAME_LEN);
/* Skip the file name */
p += filename_len;
+
+ /* Get the path name length */
+ UINT16DECODE(p, pathname_len);
+
+ /* Allocate space for the path name */
+ if(NULL == (pathname = (char *)H5MM_malloc(pathname_len + 1)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, FAIL, "memory allocation failed")
+
+ /* Get the path name */
+ HDmemcpy(pathname, p, pathname_len);
+ pathname[pathname_len] = '\0';
+
+ /* Skip the path name */
+ p += pathname_len;
+
+ /* Mark as external reference */
+ ext_ref = TRUE;
}
break;
- case H5R_OBJECT:
- case H5R_REGION:
- case H5R_ATTR:
case H5R_BADTYPE:
case H5R_MAXTYPE:
default:
- break;
+ HDassert("unknown reference type" && 0);
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
}
- switch(ref->ref_type) {
- case H5R_OBJECT:
- oloc.addr = ref->ref.addr;
- if(!H5F_addr_defined(oloc.addr) || oloc.addr == 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer")
- break;
+ /* Get object location */
+ if (ext_ref) {
+ H5G_loc_t file_loc; /* File root group location */
+
+ /* Construct a group location for root group of the file */
+ if (FAIL == H5G_root_loc(file, &file_loc))
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to create location for file")
+
+ /* Find the object's location */
+ if (H5G_loc_find(&file_loc, pathname, &loc/*out*/, H5P_LINK_ACCESS_DEFAULT, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found")
+
+ /* Find the object's type */
+ if (H5O_obj_type(loc.oloc, &obj_type, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "cannot get object type")
+ } else {
+ /* 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, dxpl_id, &rc, &obj_type) < 0 || 0 == rc)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object")
+ }
- case H5R_EXT_OBJECT:
- case H5R_EXT_REGION:
- case H5R_REGION:
+ /* Open the object */
+ switch(obj_type) {
+ case H5O_TYPE_GROUP:
{
- /* Get the object oid for the dataset */
- if (!p) p = (const uint8_t *)ref->ref.serial.buf;
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ H5G_t *group; /* Pointer to group to open */
+
+ if(NULL == (group = H5G_open(&loc, dxpl_id)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
+
+ /* Create an atom for the group */
+ if((ret_value = H5I_register(H5I_GROUP, group, app_ref)) < 0) {
+ H5G_close(group);
+ HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "can't register group")
+ } /* end if */
} /* end case */
break;
- case H5R_EXT_ATTR:
- case H5R_ATTR:
+ case H5O_TYPE_NAMED_DATATYPE:
{
- size_t attr_name_len; /* Length of the attribute name */
-
- /* Get the object oid for the dataset */
- if (!p) p = (const uint8_t *)ref->ref.serial.buf;
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
-
- /* Get the attribute name length */
- UINT16DECODE(p, attr_name_len);
- HDassert(attr_name_len < H5R_MAX_ATTR_REF_NAME_LEN);
+ H5T_t *type; /* Pointer to datatype to open */
- /* Allocate space for the attribute name */
- if(NULL == (attr_name = (char *)H5MM_malloc(attr_name_len + 1)))
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, FAIL, "memory allocation failed")
+ if(NULL == (type = H5T_open(&loc, dxpl_id)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found")
- /* Get the attribute name */
- HDmemcpy(attr_name, p, attr_name_len);
- attr_name[attr_name_len] = '\0';
+ /* Create an atom for the datatype */
+ if((ret_value = H5I_register(H5I_DATATYPE, type, app_ref)) < 0) {
+ H5T_close(type);
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "can't register datatype")
+ } /* end if */
} /* end case */
break;
- 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 */
-
- /* 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, dxpl_id, &rc, &obj_type) < 0 || 0 == rc)
- HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object")
+ case H5O_TYPE_DATASET:
+ {
+ H5D_t *dset; /* Pointer to dataset to open */
- /* Construct a group location for opening the object */
- H5G_name_reset(&path);
- loc.oloc = &oloc;
- loc.path = &path;
+ /* Get correct property list */
+ if(H5P_DEFAULT == oapl_id)
+ oapl_id = H5P_DATASET_ACCESS_DEFAULT;
+ else if(TRUE != H5P_isa_class(oapl_id, H5P_DATASET_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
- /* Open an attribute */
- if(H5R_ATTR == ref->ref_type || H5R_EXT_ATTR == ref->ref_type) {
- H5A_t *attr; /* Attribute opened */
+ /* Open the dataset */
+ if(NULL == (dset = H5D_open(&loc, oapl_id, dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found")
- /* Open the attribute */
- if(NULL == (attr = H5A_open(&loc, attr_name, dxpl_id)))
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, FAIL, "can't open attribute")
+ /* Create an atom for the dataset */
+ if((ret_value = H5I_register(H5I_DATASET, dset, app_ref)) < 0) {
+ H5D_close(dset);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register dataset")
+ } /* end if */
- /* Create an atom for the attribute */
- if((ret_value = H5I_register(H5I_ATTR, attr, app_ref)) < 0) {
- H5A_close(attr);
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTREGISTER, FAIL, "can't register attribute")
- } /* end if */
- } /* end if */
- else {
- /* Open the object */
- switch(obj_type) {
- case H5O_TYPE_GROUP:
- {
- H5G_t *group; /* Pointer to group to open */
-
- if(NULL == (group = H5G_open(&loc, dxpl_id)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
-
- /* Create an atom for the group */
- if((ret_value = H5I_register(H5I_GROUP, group, app_ref)) < 0) {
- H5G_close(group);
- HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "can't register group")
- } /* end if */
- } /* end case */
- break;
-
- case H5O_TYPE_NAMED_DATATYPE:
- {
- H5T_t *type; /* Pointer to datatype to open */
-
- if(NULL == (type = H5T_open(&loc, dxpl_id)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found")
-
- /* Create an atom for the datatype */
- if((ret_value = H5I_register(H5I_DATATYPE, type, app_ref)) < 0) {
- H5T_close(type);
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "can't register datatype")
- } /* end if */
- } /* end case */
- break;
-
- case H5O_TYPE_DATASET:
- {
- H5D_t *dset; /* Pointer to dataset to open */
-
- /* Get correct property list */
- if(H5P_DEFAULT == oapl_id)
- oapl_id = H5P_DATASET_ACCESS_DEFAULT;
- else if(TRUE != H5P_isa_class(oapl_id, H5P_DATASET_ACCESS))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
-
- /* Open the dataset */
- if(NULL == (dset = H5D_open(&loc, oapl_id, dxpl_id)))
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found")
-
- /* Create an atom for the dataset */
- if((ret_value = H5I_register(H5I_DATASET, dset, app_ref)) < 0) {
- H5D_close(dset);
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register dataset")
- } /* end if */
-
- /* TODO Keep ID of the dataset */
+ /* TODO Keep ID of the dataset */
// dset->shared->dset_id = ret_value;
- } /* end case */
- break;
+ } /* end case */
+ break;
- case H5O_TYPE_UNKNOWN:
- case H5O_TYPE_NTYPES:
- default:
- HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, FAIL, "can't identify type of object referenced")
- } /* end switch */
- } /* end else */
+ case H5O_TYPE_UNKNOWN:
+ case H5O_TYPE_NTYPES:
+ default:
+ HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, FAIL, "can't identify type of object referenced")
+ } /* end switch */
done:
- H5MM_xfree(attr_name);
+ H5MM_xfree(pathname);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5R__dereference() */
+} /* end H5R__get_object() */
/*-------------------------------------------------------------------------
- * Function: H5Rdereference3
+ * Function: H5Rget_object
*
* Purpose: Given a reference to some object, open that object and return an
* ID for that object.
@@ -1260,7 +1223,7 @@ done:
*-------------------------------------------------------------------------
*/
hid_t
-H5Rdereference3(hid_t obj_id, hid_t oapl_id, href_t _ref)
+H5Rget_object(hid_t obj_id, hid_t oapl_id, href_t _ref)
{
struct href_t *ref = (struct href_t *) _ref; /* Reference */
H5G_loc_t loc; /* Group location */
@@ -1278,13 +1241,13 @@ H5Rdereference3(hid_t obj_id, hid_t oapl_id, href_t _ref)
if(ref->ref_type <= H5R_BADTYPE || ref->ref_type >= H5R_MAXTYPE)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type")
- /* Dereference */
- if((ret_value = H5R__dereference(loc.oloc->file, oapl_id, H5AC_ind_dxpl_id, ref, TRUE)) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to dereference object")
+ /* get_object */
+ if((ret_value = H5R__get_object(loc.oloc->file, oapl_id, H5AC_ind_dxpl_id, ref, TRUE)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to get_object object")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Rdereference3() */
+} /* end H5Rget_object() */
/*-------------------------------------------------------------------------
* Function: H5R__get_region
@@ -1320,6 +1283,7 @@ H5R__get_region(H5F_t *file, hid_t dxpl_id, href_t _ref)
if (ref->ref_type == H5R_EXT_REGION) {
size_t filename_len; /* Length of the file name */
+ size_t pathname_len; /* Length of the obj path name */
/* Get the file name length */
UINT16DECODE(p, filename_len);
@@ -1327,18 +1291,28 @@ H5R__get_region(H5F_t *file, hid_t dxpl_id, href_t _ref)
/* Skip the file name */
p += filename_len;
- }
- /* Get the object oid for the dataset */
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ /* Get the path name length */
+ UINT16DECODE(p, pathname_len);
+
+ /* Skip the path name */
+ p += pathname_len;
- /* Open and copy the dataset's dataspace */
- if((ret_value = H5S_read(&oloc, dxpl_id)) == NULL)
- HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found")
+ /* Unserialize the selection */
+ if (NULL == (ret_value = H5S_decode(&p)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection")
+ } else {
+ /* Get the object oid for the dataset */
+ H5F_addr_decode(oloc.file, &p, &(oloc.addr));
- /* Unserialize the selection */
- if(H5S_SELECT_DESERIALIZE(&ret_value, &p) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection")
+ /* Open and copy the dataset's dataspace */
+ if((ret_value = H5S_read(&oloc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found")
+
+ /* Unserialize the selection */
+ if(H5S_SELECT_DESERIALIZE(&ret_value, &p) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection")
+ }
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1386,6 +1360,147 @@ done:
} /* end H5Rget_region2() */
/*-------------------------------------------------------------------------
+ * Function: H5R__get_attr
+ *
+ * Purpose: Given a reference to some attribute, open that attribute and
+ * return an ID for that attribute.
+ *
+ * Return: Valid ID on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+H5A_t *
+H5R__get_attr(H5F_t *file, hid_t dxpl_id, href_t _ref)
+{
+ H5O_loc_t oloc; /* Object location */
+ H5G_name_t path; /* Path of object */
+ H5G_loc_t loc; /* Group location */
+ char *pathname = NULL; /* Path name of the object (for external references) */
+ size_t attr_name_len; /* Length of the attribute name */
+ char *attr_name = NULL; /* Attribute name */
+ const uint8_t *p = NULL; /* Pointer to OID to store */
+ struct href_t *ref = (struct href_t *) _ref; /* Reference */
+ H5A_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(file);
+ HDassert(ref);
+ HDassert((ref->ref_type == H5R_ATTR) || (ref->ref_type == H5R_EXT_ATTR));
+
+ /* Initialize the object location */
+ H5O_loc_reset(&oloc);
+ oloc.file = file;
+
+ /* Construct a group location for opening the object */
+ H5G_name_reset(&path);
+ loc.oloc = &oloc;
+ loc.path = &path;
+
+ /* Point to reference buffer now */
+ p = (const uint8_t *)ref->ref.serial.buf;
+
+ if (ref->ref_type == H5R_EXT_ATTR) {
+ H5G_loc_t file_loc; /* File root group location */
+ size_t filename_len; /* Length of the file name */
+ size_t pathname_len; /* Length of the obj path name */
+
+ /* Get the file name length */
+ UINT16DECODE(p, filename_len);
+
+ /* Skip the file name */
+ p += filename_len;
+
+ /* Get the path name length */
+ UINT16DECODE(p, pathname_len);
+
+ /* Allocate space for the path name */
+ if(NULL == (pathname = (char *)H5MM_malloc(pathname_len + 1)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "memory allocation failed")
+
+ /* Get the path name */
+ HDmemcpy(pathname, p, pathname_len);
+ pathname[pathname_len] = '\0';
+
+ /* Skip the path name */
+ p += pathname_len;
+
+ /* Construct a group location for root group of the file */
+ if (FAIL == H5G_root_loc(file, &file_loc))
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, NULL, "unable to create location for file")
+
+ /* Find the object's location */
+ if (H5G_loc_find(&file_loc, pathname, &loc/*out*/, H5P_LINK_ACCESS_DEFAULT, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, NULL, "object not found")
+ } else {
+ /* Get the object oid for the dataset */
+ H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ }
+
+ /* Get the attribute name length */
+ UINT16DECODE(p, attr_name_len);
+ HDassert(attr_name_len < H5R_MAX_ATTR_REF_NAME_LEN);
+
+ /* Allocate space for the attribute name */
+ if(NULL == (attr_name = (char *)H5MM_malloc(attr_name_len + 1)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "memory allocation failed")
+
+ /* Get the attribute name */
+ HDmemcpy(attr_name, p, attr_name_len);
+ attr_name[attr_name_len] = '\0';
+
+ /* Open the attribute */
+ if(NULL == (ret_value = H5A_open(&loc, attr_name, dxpl_id)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTOPENOBJ, NULL, "can't open attribute")
+
+done:
+ H5MM_xfree(pathname);
+ H5MM_xfree(attr_name);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5R__get_attr() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Rget_attr
+ *
+ * Purpose: Given a reference to some attribute, open that attribute and
+ * return an ID for that attribute.
+ *
+ * Return: Valid ID on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Rget_attr(hid_t loc_id, href_t _ref)
+{
+ struct href_t *ref = (struct href_t *) _ref; /* Reference */
+ H5G_loc_t loc; /* Group location */
+ H5A_t *attr; /* Attribute */
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(ref == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer")
+ if(ref->ref_type != H5R_ATTR && ref->ref_type != H5R_EXT_ATTR)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type")
+
+ /* Get the attribute */
+ if((attr = H5R__get_attr(loc.oloc->file, H5AC_ind_dxpl_id, ref)) == NULL)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to open attribute")
+
+ /* Atomize */
+ if((ret_value = H5I_register (H5I_ATTR, attr, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute atom")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Rget_attr() */
+
+/*-------------------------------------------------------------------------
* Function: H5R__get_obj_type
*
* Purpose: Given a reference to some object, this function returns the type
@@ -1398,20 +1513,35 @@ done:
herr_t
H5R__get_obj_type(H5F_t *file, hid_t dxpl_id, href_t _ref, H5O_type_t *obj_type)
{
- H5O_loc_t oloc; /* Object location */
- unsigned rc; /* Reference count of object */
+ H5O_loc_t oloc; /* Object location */
+ H5G_name_t path; /* Path of object */
+ H5G_loc_t loc; /* Group location */
+ char *pathname = NULL; /* Path name of the object (for external references) */
+ unsigned rc; /* Reference count of object */
+ hbool_t ext_ref = FALSE; /* External reference */
+ const uint8_t *p = NULL; /* Pointer to OID to store */
struct href_t *ref = (struct href_t *) _ref; /* Reference */
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
- HDassert(ref);
HDassert(file);
+ HDassert(ref);
+ HDassert(ref->ref_type > H5R_BADTYPE && ref->ref_type < H5R_MAXTYPE);
+ HDassert(obj_type);
- /* Initialize the symbol table entry */
+ /* Initialize the object location */
H5O_loc_reset(&oloc);
oloc.file = file;
+ /* Construct a group location for opening the object */
+ H5G_name_reset(&path);
+ loc.oloc = &oloc;
+ loc.path = &path;
+
+ /* Point to reference buffer now */
+ p = (const uint8_t *)ref->ref.serial.buf;
+
switch(ref->ref_type) {
case H5R_OBJECT:
/* Get the object oid */
@@ -1419,24 +1549,41 @@ H5R__get_obj_type(H5F_t *file, hid_t dxpl_id, href_t _ref, H5O_type_t *obj_type)
break;
case H5R_REGION:
- {
- const uint8_t *p; /* Pointer to reference to decode */
-
+ case H5R_ATTR:
/* Get the object oid for the dataset */
- p = (const uint8_t *)ref->ref.serial.buf;
H5F_addr_decode(oloc.file, &p, &(oloc.addr));
-
break;
- } /* end case */
- case H5R_ATTR:
+ case H5R_EXT_OBJECT:
+ case H5R_EXT_REGION:
+ case H5R_EXT_ATTR:
{
- const uint8_t *p; /* Pointer to reference to decode */
+ size_t filename_len; /* Length of the file name */
+ size_t pathname_len; /* Length of the obj path name */
- /* Get the object oid for the dataset */
- p = (const uint8_t *)ref->ref.serial.buf;
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ /* Get the file name length */
+ UINT16DECODE(p, filename_len);
+ HDassert(filename_len < H5R_MAX_ATTR_REF_NAME_LEN);
+ /* Skip the file name */
+ p += filename_len;
+
+ /* Get the path name length */
+ UINT16DECODE(p, pathname_len);
+
+ /* Allocate space for the path name */
+ if(NULL == (pathname = (char *)H5MM_malloc(pathname_len + 1)))
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, FAIL, "memory allocation failed")
+
+ /* Get the path name */
+ HDmemcpy(pathname, p, pathname_len);
+ pathname[pathname_len] = '\0';
+
+ /* Skip the path name */
+ p += pathname_len;
+
+ /* Mark as external reference */
+ ext_ref = TRUE;
break;
} /* end case */
@@ -1447,12 +1594,30 @@ H5R__get_obj_type(H5F_t *file, hid_t dxpl_id, href_t _ref, H5O_type_t *obj_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, dxpl_id, &rc, obj_type) < 0 || 0 == rc)
- HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object")
+ if (ext_ref) {
+ H5G_loc_t file_loc; /* File root group location */
+
+ /* Construct a group location for root group of the file */
+ if (FAIL == H5G_root_loc(file, &file_loc))
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to create location for file")
+
+ /* Find the object's location */
+ if (H5G_loc_find(&file_loc, pathname, &loc/*out*/, H5P_LINK_ACCESS_DEFAULT, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found")
+
+ /* Find the object's type */
+ if (H5O_obj_type(loc.oloc, obj_type, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "cannot get object type")
+ } else {
+ /* 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, dxpl_id, &rc, obj_type) < 0 || 0 == rc)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object")
+ }
done:
+ H5MM_xfree(pathname);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5R__get_obj_type() */
@@ -1508,6 +1673,7 @@ H5R__get_obj_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t loc_id, href_t _
hid_t file_id = H5I_BADID; /* ID for file that the reference is in */
H5O_loc_t oloc; /* Object location describing object for reference */
ssize_t ret_value = -1; /* Return value */
+ hbool_t ext_ref = FALSE; /* External reference */
const uint8_t *p = NULL; /* Pointer to reference to decode */
struct href_t *ref = (struct href_t *) _ref; /* Reference */
@@ -1521,48 +1687,55 @@ H5R__get_obj_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t loc_id, href_t _
H5O_loc_reset(&oloc);
oloc.file = f;
- switch (ref->ref_type) {
+ /* Point to reference buffer now */
+ p = (const uint8_t *)ref->ref.serial.buf;
+
+ /* Get address for reference */
+ switch(ref->ref_type) {
+ case H5R_OBJECT:
+ oloc.addr = ref->ref.addr;
+ break;
+
+ case H5R_REGION:
+ case H5R_ATTR:
+ {
+ /* Get the object oid for the dataset */
+ H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ } /* end case */
+ break;
+
case H5R_EXT_OBJECT:
case H5R_EXT_REGION:
case H5R_EXT_ATTR:
{
size_t filename_len; /* Length of the file name */
+ size_t pathname_len; /* Length of the obj path name */
+ size_t copy_len;
/* Get the file name length */
- p = (const uint8_t *)ref->ref.serial.buf;
UINT16DECODE(p, filename_len);
HDassert(filename_len < H5R_MAX_ATTR_REF_NAME_LEN);
/* Skip the file name */
p += filename_len;
- }
- break;
- case H5R_OBJECT:
- case H5R_REGION:
- case H5R_ATTR:
- case H5R_BADTYPE:
- case H5R_MAXTYPE:
- default:
- break;
- }
- /* Get address for reference */
- switch(ref->ref_type) {
- case H5R_OBJECT:
- oloc.addr = ref->ref.addr;
+ /* Get the path name length */
+ UINT16DECODE(p, pathname_len);
+ copy_len = MIN(pathname_len, size - 1);
+
+ /* Get the path name */
+ if (name) {
+ HDmemcpy(name, p, copy_len);
+ name[copy_len] = '\0';
+ }
+
+ ret_value = (ssize_t)(copy_len + 1);
+
+ /* Mark as external reference */
+ ext_ref = TRUE;
+ }
break;
- case H5R_EXT_OBJECT:
- case H5R_EXT_REGION:
- case H5R_REGION:
- case H5R_EXT_ATTR:
- case H5R_ATTR:
- {
- /* Get the object oid for the dataset */
- if (!p) p = (const uint8_t *)ref->ref.serial.buf;
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
- } /* end case */
- break;
case H5R_BADTYPE:
case H5R_MAXTYPE:
default:
@@ -1570,13 +1743,16 @@ H5R__get_obj_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t loc_id, href_t _
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
} /* end switch */
- /* Retrieve file ID for name search */
- if((file_id = H5I_get_file_id(loc_id, FALSE)) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve file ID")
+ /* Get object location */
+ if (!ext_ref) {
+ /* Retrieve file ID for name search */
+ if((file_id = H5I_get_file_id(loc_id, FALSE)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve file ID")
- /* Get name, length, etc. */
- if((ret_value = H5G_get_name_by_addr(file_id, lapl_id, dxpl_id, &oloc, name, size)) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't determine name")
+ /* Get name, length, etc. */
+ if((ret_value = H5G_get_name_by_addr(file_id, lapl_id, dxpl_id, &oloc, name, size)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't determine name")
+ }
done:
/* Close file ID used for search */
@@ -1654,21 +1830,29 @@ H5R__get_attr_name(H5F_t *f, href_t _ref, char *name, size_t size)
H5O_loc_reset(&oloc);
oloc.file = f;
+ /* Point to reference buffer now */
+ p = (const uint8_t *)ref->ref.serial.buf;
+
if (ref->ref_type == H5R_EXT_ATTR) {
size_t filename_len; /* Length of the file name */
+ size_t pathname_len; /* Length of the obj path name */
/* Get the file name length */
- p = (const uint8_t *)ref->ref.serial.buf;
UINT16DECODE(p, filename_len);
HDassert(filename_len < H5R_MAX_ATTR_REF_NAME_LEN);
/* Skip the file name */
p += filename_len;
- }
- /* Get the object oid for the dataset */
- if (!p) p = (const uint8_t *)ref->ref.serial.buf;
- H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ /* Get the path name length */
+ UINT16DECODE(p, pathname_len);
+
+ /* Skip the path name */
+ p += pathname_len;
+ } else {
+ /* Get the object oid for the dataset */
+ H5F_addr_decode(oloc.file, &p, &(oloc.addr));
+ }
/* Get the attribute name length */
UINT16DECODE(p, attr_name_len);
@@ -1681,7 +1865,7 @@ H5R__get_attr_name(H5F_t *f, href_t _ref, char *name, size_t size)
name[copy_len] = '\0';
}
- ret_value = (ssize_t)copy_len;
+ ret_value = (ssize_t)(copy_len + 1);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5R__get_attr_name() */
@@ -1764,7 +1948,7 @@ H5R__get_file_name(href_t _ref, char *name, size_t size)
HDmemcpy(name, p, copy_len);
name[copy_len] = '\0';
}
- ret_value = (ssize_t)copy_len;
+ ret_value = (ssize_t)(copy_len + 1);
}
break;
case H5R_OBJECT:
@@ -1775,7 +1959,6 @@ H5R__get_file_name(href_t _ref, char *name, size_t size)
default:
HDassert("unknown reference type" && 0);
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
- break;
} /* end switch */
done: