diff options
Diffstat (limited to 'src/H5R.c')
-rw-r--r-- | src/H5R.c | 837 |
1 files changed, 510 insertions, 327 deletions
@@ -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: |