diff options
author | Jerome Soumagne <jsoumagne@hdfgroup.org> | 2015-12-03 18:33:11 (GMT) |
---|---|---|
committer | Jerome Soumagne <jsoumagne@hdfgroup.org> | 2016-11-29 23:42:31 (GMT) |
commit | f545fa003ec9319a2ac1a9b299c605adb7a86ad9 (patch) | |
tree | 00b7f137bbd01c0ce00b473bba352e314eef7122 | |
parent | 4e0eb46e0629dc33b0b953883bc605e753dbc8c2 (diff) | |
download | hdf5-f545fa003ec9319a2ac1a9b299c605adb7a86ad9.zip hdf5-f545fa003ec9319a2ac1a9b299c605adb7a86ad9.tar.gz hdf5-f545fa003ec9319a2ac1a9b299c605adb7a86ad9.tar.bz2 |
Add external references
Remove dataset region reference and use new region reference instead
Fix reference conversion code
Modify reference API to use opaque type
-rwxr-xr-x | bin/trace | 2 | ||||
-rw-r--r-- | src/H5Aint.c | 11 | ||||
-rw-r--r-- | src/H5Dchunk.c | 10 | ||||
-rw-r--r-- | src/H5Dcompact.c | 11 | ||||
-rw-r--r-- | src/H5Dcontig.c | 13 | ||||
-rw-r--r-- | src/H5Dio.c | 5 | ||||
-rw-r--r-- | src/H5Ocopy.c | 199 | ||||
-rw-r--r-- | src/H5Odtype.c | 17 | ||||
-rw-r--r-- | src/H5Oprivate.h | 3 | ||||
-rw-r--r-- | src/H5R.c | 1546 | ||||
-rw-r--r-- | src/H5Rdeprec.c | 12 | ||||
-rw-r--r-- | src/H5Rpkg.h | 8 | ||||
-rw-r--r-- | src/H5Rprivate.h | 24 | ||||
-rw-r--r-- | src/H5Rpublic.h | 62 | ||||
-rw-r--r-- | src/H5T.c | 132 | ||||
-rw-r--r-- | src/H5Tconv.c | 96 | ||||
-rw-r--r-- | src/H5Tnative.c | 47 | ||||
-rw-r--r-- | src/H5Tpkg.h | 7 | ||||
-rw-r--r-- | src/H5Tpublic.h | 8 | ||||
-rw-r--r-- | src/H5Tref.c | 291 | ||||
-rw-r--r-- | src/H5detect.c | 10 | ||||
-rw-r--r-- | src/H5trace.c | 10 |
22 files changed, 1403 insertions, 1121 deletions
@@ -78,7 +78,7 @@ $Source = ""; "H5Q_type_t" => "Qt", "H5Q_match_op_t" => "Qm", "H5Q_combine_op_t" => "Qc", - "hobj_ref_t" => "r", + "href_t" => "r", "H5R_type_t" => "Rt", "char" => "s", "unsigned char" => "s", diff --git a/src/H5Aint.c b/src/H5Aint.c index cd5408d..6937758 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -2279,15 +2279,8 @@ H5A_attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *attr_src, /* Check for expanding references */ if(cpy_info->expand_ref) { - size_t ref_count; - - /* Determine # of reference elements to copy */ - ref_count = attr_dst->shared->data_size / H5T_get_size(attr_dst->shared->dt); - - /* Copy objects referenced in source buffer to destination file and set destination elements */ - if(H5O_copy_expand_ref(file_src, attr_dst->shared->data, dxpl_id, - file_dst, attr_dst->shared->data, ref_count, H5T_get_ref_type(attr_dst->shared->dt), cpy_info) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") + /* TODO needs to be implemented (should use H5Tconvert) */ + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") } /* end if */ else /* Reset value to zero */ diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 7e73a4a..9c1df42 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -4772,14 +4772,8 @@ H5D__chunk_copy_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) /* Check for expanding references */ /* (background buffer has already been zeroed out, if not expanding) */ if(udata->cpy_info->expand_ref) { - size_t ref_count; - - /* Determine # of reference elements to copy */ - ref_count = nbytes / H5T_get_size(udata->dt_src); - - /* Copy the reference elements */ - if(H5O_copy_expand_ref(udata->file_src, buf, udata->idx_info_dst->dxpl_id, udata->idx_info_dst->f, bkg, ref_count, H5T_get_ref_type(udata->dt_src), udata->cpy_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy reference attribute") + /* TODO needs to be implemented (should use H5Tconvert) */ + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy reference attribute") } /* end if */ /* After fix ref, copy the new reference elements to the buffer to write out */ diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c index ebe75bd..20d80cb 100644 --- a/src/H5Dcompact.c +++ b/src/H5Dcompact.c @@ -556,15 +556,8 @@ H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src, H5F_t *f_dst if(f_src != f_dst) { /* Check for expanding references */ if(cpy_info->expand_ref) { - size_t ref_count; - - /* Determine # of reference elements to copy */ - ref_count = storage_src->size / H5T_get_size(dt_src); - - /* Copy objects referenced in source buffer to destination file and set destination elements */ - if(H5O_copy_expand_ref(f_src, storage_src->buf, dxpl_id, f_dst, - storage_dst->buf, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") + /* TODO needs to be implemented (should use H5Tconvert) */ + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") } /* end if */ else /* Reset value to zero */ diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index 988bb61..78c6f43 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -1546,17 +1546,8 @@ H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage_src, else if(fix_ref) { /* Check for expanding references */ if(cpy_info->expand_ref) { - size_t ref_count; - - /* Determine # of reference elements to copy */ - ref_count = src_nbytes / H5T_get_size(dt_src); - - /* Copy the reference elements */ - if(H5O_copy_expand_ref(f_src, buf, dxpl_id, f_dst, bkg, ref_count, H5T_get_ref_type(dt_src), cpy_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") - - /* After fix ref, copy the new reference elements to the buffer to write out */ - HDmemcpy(buf, bkg, buf_size); + /* TODO needs to be implemented (should use H5Tconvert) */ + HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy reference attribute") } /* end if */ else /* Reset value to zero */ diff --git a/src/H5Dio.c b/src/H5Dio.c index 138c746..cfbcb9e 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -720,9 +720,8 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, /* We should really use H5T_detect_class() here, but it will be difficult * to detect the type of the reference if it is nested... -QAK */ - if(H5T_get_class(type_info.mem_type, TRUE) == H5T_REFERENCE && - H5T_get_ref_type(type_info.mem_type) == H5R_DATASET_REGION) - HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing region reference datatypes yet") + if(H5T_get_class(type_info.mem_type, TRUE) == H5T_REFERENCE) + HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing reference datatypes yet") /* Can't write to chunked datasets with filters, in parallel */ if(dataset->shared->layout.type == H5D_CHUNKED && diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index e641d70..4488cd1 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -88,8 +88,6 @@ static herr_t H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*o hid_t dxpl_id, hid_t ocpypl_id); static herr_t H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id); -static herr_t H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, - H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info); static herr_t H5O_copy_free_comm_dt_cb(void *item, void *key, void *op_data); static int H5O_copy_comm_dt_cmp(const void *dt1, const void *dt2); static herr_t H5O_copy_search_comm_dt_cb(hid_t group, const char *name, @@ -1203,203 +1201,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_copy_obj_by_ref - * - * Purpose: Copy the object pointed by _src_ref. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Peter Cao - * Aug 7 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, H5O_loc_t *dst_oloc, - H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(src_oloc); - HDassert(dst_oloc); - - /* Perform the copy, or look up existing copy */ - if((ret_value = H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, - FALSE, NULL, NULL)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - - /* Check if a new valid object is copied to the destination */ - if(H5F_addr_defined(dst_oloc->addr) && (ret_value > SUCCEED)) { - char tmp_obj_name[80]; - H5G_name_t new_path; - H5O_loc_t new_oloc; - H5G_loc_t new_loc; - - /* Set up group location for new object */ - new_loc.oloc = &new_oloc; - new_loc.path = &new_path; - H5G_loc_reset(&new_loc); - new_oloc.file = dst_oloc->file; - new_oloc.addr = dst_oloc->addr; - - /* Pick a default name for the new object */ - HDsnprintf(tmp_obj_name, sizeof(tmp_obj_name), "~obj_pointed_by_%llu", (unsigned long long)dst_oloc->addr); - - /* Create a link to the newly copied object */ - /* Note: since H5O_copy_header_map actually copied the target object, it - * must exist either in cache or on disk, therefore it is is safe to not - * pass the obj_type and udata fields returned by H5O_copy_header_map. - * This could be changed in the future to slightly improve performance - * --NAF */ - if(H5L_link(dst_root_loc, tmp_obj_name, &new_loc, H5P_DEFAULT, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link") - - H5G_loc_free(&new_loc); - } /* if (H5F_addr_defined(dst_oloc.addr)) */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_copy_obj_by_ref() */ - - -/*------------------------------------------------------------------------- - * Function: H5O_copy_expand_ref - * - * Purpose: Copy the object pointed by _src_ref. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Peter Cao - * Aug 7 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, - H5F_t *file_dst, void *_dst_ref, size_t ref_count, H5R_type_t ref_type, - H5O_copy_t *cpy_info) -{ - H5O_loc_t dst_oloc; /* Copied object object location */ - H5O_loc_t src_oloc; /* Temporary object location for source object */ - H5G_loc_t dst_root_loc; /* The location of root group of the destination file */ - const uint8_t *q; /* Pointer to source OID to store */ - uint8_t *p; /* Pointer to destination OID to store */ - size_t i; /* Local index variable */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity checks */ - HDassert(file_src); - HDassert(_src_ref); - HDassert(file_dst); - HDassert(_dst_ref); - HDassert(ref_count); - HDassert(cpy_info); - - /* Initialize object locations */ - H5O_loc_reset(&src_oloc); - H5O_loc_reset(&dst_oloc); - src_oloc.file = file_src; - dst_oloc.file = file_dst; - - /* Set up the root group in the destination file */ - if(NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(file_dst)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") - if(NULL == (dst_root_loc.path = H5G_nameof(H5G_rootof(file_dst)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") - - /* Copy object references */ - if(H5R_OBJECT == ref_type) { - hobj_ref_t *src_ref = (hobj_ref_t *)_src_ref; - hobj_ref_t *dst_ref = (hobj_ref_t *)_dst_ref; - - /* Making equivalent references in the destination file */ - for(i = 0; i < ref_count; i++) { - /* Set up for the object copy for the reference */ - q = (uint8_t *)(&src_ref[i]); - H5F_addr_decode(src_oloc.file, (const uint8_t **)&q, &(src_oloc.addr)); - dst_oloc.addr = HADDR_UNDEF; - - /* Attempt to copy object from source to destination file */ - if(src_oloc.addr != (haddr_t)0) { - if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - } /* end if */ - else - /* Set parameters so the reference is written as all 0's */ - HDmemset(&dst_oloc.addr, 0, sizeof(dst_oloc.addr)); - - /* Set the object reference info for the destination file */ - p = (uint8_t *)(&dst_ref[i]); - H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); - } /* end for */ - } /* end if */ - /* Copy region references */ - else if(H5R_DATASET_REGION == ref_type) { - hdset_reg_ref_t *src_ref = (hdset_reg_ref_t *)_src_ref; - hdset_reg_ref_t *dst_ref = (hdset_reg_ref_t *)_dst_ref; - uint8_t *buf = NULL; /* Buffer to store serialized selection in */ - H5HG_t hobjid; /* Heap object ID */ - size_t buf_size; /* Length of object in heap */ - - /* Making equivalent references in the destination file */ - for(i = 0; i < ref_count; i++) { - /* Get the heap ID for the dataset region */ - q = (const uint8_t *)(&src_ref[i]); - H5F_addr_decode(src_oloc.file, (const uint8_t **)&q, &(hobjid.addr)); - UINT32DECODE(q, hobjid.idx); - - if(hobjid.addr != (haddr_t)0) { - /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = (uint8_t *)H5HG_read(src_oloc.file, dxpl_id, &hobjid, NULL, &buf_size)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") - - /* Get the object oid for the dataset */ - q = (const uint8_t *)buf; - H5F_addr_decode(src_oloc.file, (const uint8_t **)&q, &(src_oloc.addr)); - dst_oloc.addr = HADDR_UNDEF; - - /* copy the object pointed by the ref to the destination */ - if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) { - H5MM_xfree(buf); - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - } /* end if */ - - /* Serialize object ID */ - p = (uint8_t *)buf; - H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); - - /* Save the serialized buffer to the destination */ - if(H5HG_insert(dst_oloc.file, dxpl_id, buf_size, buf, &hobjid) < 0) { - H5MM_xfree(buf); - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to write dataset region information") - } /* end if */ - } /* end if */ - else - /* Set parameters so the reference is written as all 0's */ - HDmemset(&hobjid, 0, sizeof(hobjid)); - - /* Set the dataset region reference info for the destination file */ - p = (uint8_t *)(&dst_ref[i]); - H5F_addr_encode(dst_oloc.file, &p, hobjid.addr); - UINT32ENCODE(p, hobjid.idx); - - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); - } /* end for */ - } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_copy_expand_ref() */ - - -/*------------------------------------------------------------------------- * Function: H5O_copy_free_comm_dt_cb * * Purpose: Frees the merge committed dt skip list key and object. diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 748ff70..5091614 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -438,17 +438,12 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p /* Set reference type */ dt->shared->u.atomic.u.r.rtype = (H5R_type_t)(flags & 0x0f); - /* Set extra information for object references, so the hobj_ref_t gets swizzled correctly */ - if(dt->shared->u.atomic.u.r.rtype == H5R_OBJECT - || dt->shared->u.atomic.u.r.rtype == H5R_REGION - || dt->shared->u.atomic.u.r.rtype == H5R_ATTR) { - /* Mark location this type as undefined for now. The caller function should - * decide the location. */ - dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; - - /* This type needs conversion */ - dt->shared->force_conv = TRUE; - } /* end if */ + /* Mark location this type as undefined for now. The caller function should + * decide the location. */ + dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; + + /* This type needs conversion */ + dt->shared->force_conv = TRUE; break; case H5T_ENUM: diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 1f71be6..23a05ff 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -828,9 +828,6 @@ H5_DLL herr_t H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_ H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth, H5O_type_t *obj_type, void **udata); -H5_DLL herr_t H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, - H5F_t *file_dst, void *_dst_ref, size_t ref_count, H5R_type_t ref_type, - H5O_copy_t *cpy_info); /* Debugging routines */ H5_DLL herr_t H5O_debug_id(unsigned type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth); @@ -17,23 +17,23 @@ /* Module Setup */ /****************/ -#include "H5Rmodule.h" /* This source code file is part of the H5R module */ +#include "H5Rmodule.h" /* This source code file is part of the H5R module */ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5ACprivate.h" /* Metadata cache */ -#include "H5Aprivate.h" /* Attributes */ -#include "H5Dprivate.h" /* Datasets */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Gprivate.h" /* Groups */ -#include "H5HGprivate.h" /* Global Heaps */ -#include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Rpkg.h" /* References */ -#include "H5Sprivate.h" /* Dataspaces */ +#include "H5private.h" /* Generic Functions */ +#include "H5ACprivate.h" /* Metadata cache */ +#include "H5Aprivate.h" /* Attributes */ +#include "H5Dprivate.h" /* Datasets */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Gprivate.h" /* Groups */ +#include "H5HGprivate.h" /* Global Heaps */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Rpkg.h" /* References */ +#include "H5Sprivate.h" /* Dataspaces */ /****************/ @@ -41,7 +41,6 @@ /****************/ #define H5R_MAX_ATTR_REF_NAME_LEN (64 * 1024) - /******************/ /* Local Typedefs */ /******************/ @@ -51,9 +50,10 @@ /* Local Prototypes */ /********************/ -static H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref); -static ssize_t H5R_get_name(H5F_t *file, hid_t lapl_id, hid_t dxpl_id, hid_t id, - H5R_type_t ref_type, const void *_ref, char *name, size_t size); +static H5S_t * H5R__get_region(H5F_t *file, hid_t dxpl_id, const href_t *_ref); +static ssize_t H5R__get_name(H5F_t *file, hid_t lapl_id, hid_t dxpl_id, hid_t id, + const href_t *_ref, char *name, size_t size); +static ssize_t H5R__get_filename(const href_t *ref, char *name, size_t size); /*********************/ @@ -84,7 +84,6 @@ static const H5I_class_t H5I_REFERENCE_CLS[1] = {{ /* Flag indicating "top" of interface has been initialized */ static hbool_t H5R_top_package_initialize_s = FALSE; - /*-------------------------------------------------------------------------- NAME @@ -203,517 +202,805 @@ H5R_term_package(void) /*-------------------------------------------------------------------------- NAME - H5R_create + H5R_create_object PURPOSE Creates a particular kind of reference for the user USAGE - herr_t H5R_create(ref, ref_type, ...) - void *ref; OUT: Reference created - H5R_type_t ref_type; IN: Type of reference to create - Additional arguments: - H5G_loc_t *loc; IN: File location used to locate object pointed to - const char *name; IN: Name of object at location of object pointed to - hid_t dxpl_id; IN: Property list ID - H5S_t *space; IN: Dataspace with selection, used for Dataset - Region references. - const char *attr_name; IN: Name of attribute pointed to, used for - Attribute references. + href_t *H5R_create_object(loc, name, dxpl_id) + H5G_loc_t *loc; IN: File location used to locate object pointed to + const char *name; IN: Name of object at location of object pointed to + hid_t dxpl_id; IN: Property list ID RETURNS - Non-negative on success/Negative on failure + Reference created on success/NULL 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) or ATTR_NAME is used to choose tha attribute - pointed to (for Attribute references). - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG + space pointed to by REF. The LOC and NAME are used to locate the object + pointed to. --------------------------------------------------------------------------*/ -herr_t -H5R_create(void *_ref, H5R_type_t ref_type, ...) +href_t * +H5R_create_object(H5G_loc_t *loc, const char *name, hid_t dxpl_id) { 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 */ - uint8_t *buf = NULL; /* Buffer to store serialized selection in */ hbool_t obj_found = FALSE; /* Object location found */ - va_list ap; - herr_t ret_value = SUCCEED; /* Return value */ + href_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT - HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE); + 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; + + if(NULL == (ret_value = (href_t *)H5MM_malloc(sizeof(href_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Cannot allocate memory for reference") + + ret_value->ref_type = H5R_OBJECT; + ret_value->obj_addr = obj_loc.oloc->addr; + +done: + if(obj_found) + H5G_loc_free(&obj_loc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R_create_object() */ - va_start(ap, ref_type); +/*-------------------------------------------------------------------------- + NAME + H5R_create_region + PURPOSE + Creates a particular kind of reference for the user + USAGE + href_t *H5R_create_region(loc, name, dxpl_id, space) + H5G_loc_t *loc; IN: File location used to locate object pointed to + const char *name; IN: Name of object at location of object pointed to + hid_t dxpl_id; IN: Property list ID + H5S_t *space; IN: Dataspace with selection, used for Dataset + Region references. + + RETURNS + Reference created on success/NULL on failure + DESCRIPTION + Creates a particular type of reference specified with REF_TYPE, in the + space pointed to by REF. The LOC and NAME are used to locate the object + pointed to and the SPACE is used to choose the region pointed to. +--------------------------------------------------------------------------*/ +href_t * +H5R_create_region(H5G_loc_t *loc, const char *name, hid_t dxpl_id, 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 */ + hssize_t buf_size; /* Size of buffer needed to serialize selection */ + uint8_t *p; /* Pointer to OID to store */ + href_t *ref = NULL; /* Reference to be returned */ + href_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(loc); + HDassert(name); + HDassert(space); /* Set up object location to fill in */ obj_loc.oloc = &oloc; obj_loc.path = &path; H5G_loc_reset(&obj_loc); - switch(ref_type) { - case H5R_OBJECT: - { - H5G_loc_t *loc; - const char *name; - hid_t dxpl_id; - hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */ - - /* Get arguments */ - loc = va_arg(ap, H5G_loc_t *); - name = va_arg(ap, const char *); - dxpl_id = va_arg(ap, hid_t); - - HDassert(ref); - HDassert(loc); - HDassert(name); - - /* Find the object */ - if(H5G_loc_find(loc, name, &obj_loc, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found") - obj_found = TRUE; - - *ref = obj_loc.oloc->addr; - break; - } + /* 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; - case H5R_DATASET_REGION: - { - H5G_loc_t *loc; - const char *name; - hid_t dxpl_id; - 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 */ - hbool_t heapid_found; /* Flag for non-zero heap ID found */ - unsigned u; /* local index */ - H5S_t *space; - - /* Get arguments */ - loc = va_arg(ap, H5G_loc_t *); - name = va_arg(ap, const char *); - dxpl_id = va_arg(ap, hid_t); - space = va_arg(ap, H5S_t *); - - HDassert(ref); - HDassert(loc); - HDassert(name); - HDassert(space); - - /* Find the object */ - if(H5G_loc_find(loc, name, &obj_loc, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found") - obj_found = TRUE; - - /* 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 = FALSE, p = (uint8_t *)ref; u < H5R_DSET_REG_REF_BUF_SIZE; u++) - if(p[u] != 0) { - heapid_found = TRUE; - break; - } /* end if */ + /* 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(heapid_found) { -/* Return heap block to free list */ - } /* end if */ - } /* end if */ + /* Increase buffer size to allow for the dataset OID */ + buf_size += (hssize_t)sizeof(haddr_t); - /* Zero the heap ID out, may leak heap space if user is re-using reference and doesn't have garbage collection on */ - HDmemset(ref, 0, H5R_DSET_REG_REF_BUF_SIZE); + /* Allocate the space to store the serialized information */ + H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t); + if(NULL == (ref = (href_t *)H5MM_malloc(sizeof(href_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Cannot allocate memory for reference") + if (NULL == (ref->obj_enc.buf = H5MM_malloc((size_t) buf_size))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "Cannot allocate buffer to serialize selection") + ref->obj_enc.buf_size = (size_t) buf_size; + ref->ref_type = H5R_REGION; - /* 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") + /* Serialize information for dataset OID into buffer */ + p = (uint8_t *)ref->obj_enc.buf; + H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); - /* Increase buffer size to allow for the dataset OID */ - buf_size += (hssize_t)sizeof(haddr_t); + /* Serialize the selection into buffer */ + if(H5S_SELECT_SERIALIZE(space, &p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, NULL, "Unable to serialize selection") - /* 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") + ret_value = ref; - /* Serialize information for dataset OID into heap buffer */ - p = (uint8_t *)buf; - H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); +done: + if(obj_found) + H5G_loc_free(&obj_loc); + if(NULL == ret_value) { + H5MM_free(ref->obj_enc.buf); + H5MM_free(ref); + } - /* Serialize the selection into heap buffer */ - if(H5S_SELECT_SERIALIZE(space, &p) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R_create_region */ - /* Save the serialized buffer for later */ - if(H5HG_insert(loc->oloc->file, dxpl_id, (size_t)buf_size, buf, &hobjid) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection") +/*-------------------------------------------------------------------------- + NAME + H5R_create_attr + PURPOSE + Creates a particular kind of reference for the user + USAGE + href_t *H5R_create_attr(loc, name, dxpl_id, attr_name) + H5G_loc_t *loc; IN: File location used to locate object pointed to + const char *name; IN: Name of object at location of object pointed to + hid_t dxpl_id; IN: Property list ID + const char *attr_name; IN: Name of attribute pointed to, used for + Attribute references. - /* 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); + RETURNS + Reference created on success/NULL on failure + DESCRIPTION + Creates a particular type of reference specified with REF_TYPE, in the + space pointed to by REF. The LOC, NAME and ATTR_NAME are used to locate + the attribute pointed to. +--------------------------------------------------------------------------*/ +href_t * +H5R_create_attr(H5G_loc_t *loc, const char *name, hid_t dxpl_id, 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 buf_size; /* Size of buffer needed to serialize attribute */ + size_t attr_name_len; /* Length of the attribute name */ + uint8_t *p; /* Pointer to OID to store */ + href_t *ref = NULL; /* Reference to be returned */ + href_t *ret_value = NULL; /* Return value */ - break; - } + FUNC_ENTER_NOAPI_NOINIT - case H5R_REGION: - { - H5G_loc_t *loc; - const char *name; - hid_t dxpl_id; - hreg_ref_t *ref = (hreg_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 */ - H5S_t *space; - - /* Get arguments */ - loc = va_arg(ap, H5G_loc_t *); - name = va_arg(ap, const char *); - dxpl_id = va_arg(ap, hid_t); - space = va_arg(ap, H5S_t *); - - HDassert(ref); - HDassert(loc); - HDassert(name); - HDassert(space); - - /* Find the object */ - if(H5G_loc_find(loc, name, &obj_loc, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found") - obj_found = TRUE; - - /* 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(!ref->buf || ref->buf_size < (size_t) buf_size) { - ref->buf_size = (size_t)buf_size; - } else { - /* Serialize information for dataset OID into buffer */ - p = (uint8_t *)ref->buf; - H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); - - /* Serialize the selection into buffer */ - if(H5S_SELECT_SERIALIZE(space, &p) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection") - } - } - break; + HDassert(loc); + HDassert(name); + HDassert(attr_name); - case H5R_ATTR: - { - H5G_loc_t *loc; - const char *name; - hid_t dxpl_id; - hattr_ref_t *ref = (hattr_ref_t *)_ref; /* Get pointer to correct type of reference struct */ - size_t buf_size; /* Size of buffer needed to serialize attribute */ - size_t attr_name_len; /* Length of the attribute name */ - uint8_t *p; /* Pointer to OID to store */ - const char *attr_name; - - /* Get arguments */ - loc = va_arg(ap, H5G_loc_t *); - name = va_arg(ap, const char *); - dxpl_id = va_arg(ap, hid_t); - attr_name = va_arg(ap, const char *); - - HDassert(ref); - HDassert(loc); - HDassert(name); - HDassert(attr_name); - - /* Find the object */ - if(H5G_loc_find(loc, name, &obj_loc, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "object not found") - obj_found = TRUE; - - /* 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, FAIL, "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); - - /* Allocate the space to store the serialized information */ - if(!ref->buf || ref->buf_size < buf_size) { - ref->buf_size = buf_size; - } else { - /* Serialize information for object's OID into buffer */ - p = (uint8_t *)ref->buf; - H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); - - /* Serialize information for attribute name length into the buffer */ - UINT16ENCODE(p, attr_name_len); - - /* Copy the attribute name into the buffer */ - HDmemcpy(p, attr_name, attr_name_len); - - /* Sanity check */ - HDassert((size_t)((p + attr_name_len) - (uint8_t *)ref->buf) == buf_size); - } - } - break; + /* Set up object location to fill in */ + obj_loc.oloc = &oloc; + obj_loc.path = &path; + H5G_loc_reset(&obj_loc); - 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 */ + /* 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; + + /* 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 = attr_name_len + 2 + sizeof(haddr_t); + + /* Allocate the space to store the serialized information */ + if(NULL == (ref = (href_t *)H5MM_malloc(sizeof(href_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Cannot allocate memory for reference") + if (NULL == (ref->obj_enc.buf = H5MM_malloc((size_t) buf_size))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "Cannot allocate buffer to serialize selection") + ref->obj_enc.buf_size = (size_t) buf_size; + ref->ref_type = H5R_ATTR; + + /* Serialize information for object's OID into buffer */ + p = (uint8_t *)ref->obj_enc.buf; + H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); + + /* Serialize information for attribute name length into the buffer */ + UINT16ENCODE(p, attr_name_len); + + /* Copy the attribute name into the buffer */ + HDmemcpy(p, attr_name, attr_name_len); + + /* Sanity check */ + HDassert((size_t)((p + attr_name_len) - (uint8_t *)ref->obj_enc.buf) == buf_size); + + ret_value = ref; + +done: + if(obj_found) + H5G_loc_free(&obj_loc); + if(NULL == ret_value) { + H5MM_free(ref->obj_enc.buf); + H5MM_free(ref); + } + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R_create_attr */ + +/*-------------------------------------------------------------------------- + NAME + H5R_create_ext_object + PURPOSE + Creates a particular kind of reference for the user + USAGE + href_t *H5R_create_ext_object(loc, name, dxpl_id) + H5G_loc_t *loc; IN: File location used to locate object pointed to + const char *name; IN: Name of object at location of object pointed to + hid_t dxpl_id; IN: Property list ID + + RETURNS + Reference created on success/NULL on failure + DESCRIPTION + Creates a particular type of reference specified with REF_TYPE, in the + space pointed to by REF. The LOC and NAME are used to locate the object + pointed to. +--------------------------------------------------------------------------*/ +href_t * +H5R_create_ext_object(H5G_loc_t *loc, const char *name, hid_t dxpl_id) +{ + 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 reference */ + uint8_t *p; /* Pointer to OID to store */ + href_t *ref = NULL; /* Reference to be returned */ + href_t *ret_value = NULL; /* Return value */ + + 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; + + /* Need to add name of the file */ + filename_len = HDstrlen(H5F_OPEN_NAME(loc->oloc->file)); + + /* Compute buffer size, allow for the attribute name length and object's OID */ + buf_size = filename_len + 2 + sizeof(haddr_t); + + if(NULL == (ref = (href_t *)H5MM_malloc(sizeof(href_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Cannot allocate memory for reference") + if (NULL == (ref->obj_enc.buf = H5MM_malloc((size_t) buf_size))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "Cannot allocate buffer to serialize selection") + ref->obj_enc.buf_size = (size_t) buf_size; + ref->ref_type = H5R_EXT_OBJECT; + + /* Serialize information for file name length into the buffer */ + p = (uint8_t *)ref->obj_enc.buf; + UINT16ENCODE(p, filename_len); + + /* Copy the file name into the buffer */ + HDmemcpy(p, H5F_OPEN_NAME(loc->oloc->file), filename_len); + p += filename_len; + + /* Serialize information for object's OID into buffer */ + H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); + + ret_value = ref; done: if(obj_found) H5G_loc_free(&obj_loc); + if(NULL == ret_value) { + H5MM_free(ref->obj_enc.buf); + H5MM_free(ref); + } - H5MM_free(buf); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R_create_ext_object() */ - va_end(ap); +/*-------------------------------------------------------------------------- + NAME + H5R_create_ext_region + PURPOSE + Creates a particular kind of reference for the user + USAGE + href_t *H5R_create_ext_region(loc, name, dxpl_id, space) + H5G_loc_t *loc; IN: File location used to locate object pointed to + const char *name; IN: Name of object at location of object pointed to + hid_t dxpl_id; IN: Property list ID + H5S_t *space; IN: Dataspace with selection, used for Dataset + Region references. + + RETURNS + Reference created on success/NULL on failure + DESCRIPTION + Creates a particular type of reference specified with REF_TYPE, in the + space pointed to by REF. The LOC and NAME are used to locate the object + pointed to and the SPACE is used to choose the region pointed to. +--------------------------------------------------------------------------*/ +href_t * +H5R_create_ext_region(H5G_loc_t *loc, const char *name, hid_t dxpl_id, 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 */ + href_t *ref = NULL; /* Reference to be returned */ + href_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(loc); + HDassert(name); + 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)); + + /* 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") + + /* Increase buffer size to allow for the dataset OID */ + buf_size += (hssize_t)(sizeof(haddr_t) + 2 + filename_len); + + /* Allocate the space to store the serialized information */ + H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t); + if(NULL == (ref = (href_t *)H5MM_malloc(sizeof(href_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Cannot allocate memory for reference") + if (NULL == (ref->obj_enc.buf = H5MM_malloc((size_t) buf_size))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "Cannot allocate buffer to serialize selection") + ref->obj_enc.buf_size = (size_t) buf_size; + ref->ref_type = H5R_EXT_REGION; + + /* Serialize information for file name length into the buffer */ + p = (uint8_t *)ref->obj_enc.buf; + UINT16ENCODE(p, filename_len); + + /* Copy the file name into the buffer */ + HDmemcpy(p, H5F_OPEN_NAME(loc->oloc->file), filename_len); + p += filename_len; + + /* Serialize information for dataset OID into buffer */ + H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr); + + /* Serialize the selection into buffer */ + if(H5S_SELECT_SERIALIZE(space, &p) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, NULL, "Unable to serialize selection") + + ret_value = ref; + +done: + if(obj_found) + H5G_loc_free(&obj_loc); + if(NULL == ret_value) { + H5MM_free(ref->obj_enc.buf); + H5MM_free(ref); + } FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R_create() */ +} /* H5R_create_ext_region */ + +/*-------------------------------------------------------------------------- + NAME + H5R_create_ext_attr + PURPOSE + Creates a particular kind of reference for the user + USAGE + href_t *H5R_create_ext_attr(loc, name, dxpl_id, attr_name) + H5G_loc_t *loc; IN: File location used to locate object pointed to + const char *name; IN: Name of object at location of object pointed to + hid_t dxpl_id; IN: Property list ID + const char *attr_name; IN: Name of attribute pointed to, used for + Attribute references. + + RETURNS + Reference created on success/NULL on failure + DESCRIPTION + Creates a particular type of reference specified with REF_TYPE, in the + space pointed to by REF. The LOC, NAME and ATTR_NAME are used to locate + the attribute pointed to. +--------------------------------------------------------------------------*/ +href_t * +H5R_create_ext_attr(H5G_loc_t *loc, const char *name, hid_t dxpl_id, 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 attr_name_len; /* Length of the attribute name */ + uint8_t *p; /* Pointer to OID to store */ + href_t *ref = NULL; /* Reference to be returned */ + href_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(loc); + HDassert(name); + 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)); + + /* 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); + + /* Allocate the space to store the serialized information */ + if(NULL == (ref = (href_t *)H5MM_malloc(sizeof(href_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "Cannot allocate memory for reference") + if (NULL == (ref->obj_enc.buf = H5MM_malloc((size_t) buf_size))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "Cannot allocate buffer to serialize selection") + ref->obj_enc.buf_size = (size_t) buf_size; + ref->ref_type = H5R_EXT_ATTR; + + /* Serialize information for file name length into the buffer */ + p = (uint8_t *)ref->obj_enc.buf; + UINT16ENCODE(p, filename_len); + + /* Copy the file name into the buffer */ + HDmemcpy(p, H5F_OPEN_NAME(loc->oloc->file), 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 attribute name length into the buffer */ + UINT16ENCODE(p, attr_name_len); + + /* Copy the attribute name into the buffer */ + HDmemcpy(p, attr_name, attr_name_len); + + /* Sanity check */ + HDassert((size_t)((p + attr_name_len) - (uint8_t *)ref->obj_enc.buf) == buf_size); + + ret_value = ref; + +done: + if(obj_found) + H5G_loc_free(&obj_loc); + if(NULL == ret_value) { + H5MM_free(ref->obj_enc.buf); + H5MM_free(ref); + } + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5R_create_ext_attr */ /*-------------------------------------------------------------------------- NAME - H5Rcreate + H5Rcreate_object PURPOSE Creates a particular kind of reference for the user USAGE - herr_t H5Rcreate(ref, ref_type, ...) - void *ref; OUT: Reference created - H5R_type_t ref_type; IN: Type of reference to create - Additional arguments: - hid_t loc_id; IN: Location ID used to locate object pointed to - const char *name; IN: Name of object at location LOC_ID of object - pointed to - hid_t space_id; IN: Dataspace ID with selection, used for Dataset - Region references. - const char *attr_name; IN: Name of attribute pointed to, used for - Attribute references. + href_t *H5Rcreate_object(loc_id, name) + hid_t loc_id; IN: Location ID used to locate object pointed to + const char *name; IN: Name of object at location LOC_ID of object + pointed to RETURNS - Non-negative on success/Negative on failure + Reference created on success/NULL 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 + pointed to. --------------------------------------------------------------------------*/ -herr_t -H5Rcreate(void *ref, H5R_type_t ref_type, ...) +href_t * +H5Rcreate_object(hid_t loc_id, const char *name) { - H5S_t *space = NULL; /* Pointer to dataspace containing region */ - va_list ap; - herr_t ret_value = FAIL; /* Return value */ + H5G_loc_t loc; /* File location */ + href_t *ret_value = NULL; /* Return value */ - FUNC_ENTER_API(FAIL) - H5TRACE2("e", "*xRt", ref, ref_type); + FUNC_ENTER_API(NULL) - va_start(ap, ref_type); + /* 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(NULL == (ret_value = H5R_create_object(&loc, name, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, NULL, "unable to create object reference") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rcreate_object() */ + +/*-------------------------------------------------------------------------- + NAME + H5Rcreate_region + PURPOSE + Creates a particular kind of reference for the user + USAGE + href_t *H5Rcreate_region(loc_id, name, space_id) + hid_t loc_id; IN: Location ID used to locate object pointed to + const char *name; IN: Name of object at location LOC_ID of object + pointed to + hid_t space_id; IN: Dataspace ID with selection, used for Dataset + Region references. + + RETURNS + Reference created on success/NULL 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. +--------------------------------------------------------------------------*/ +href_t * +H5Rcreate_region(hid_t loc_id, const char *name, 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(ref == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + 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(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_region(&loc, name, H5AC_dxpl_id, space))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, NULL, "unable to create region reference") - switch (ref_type) { - case H5R_OBJECT: - { - hid_t loc_id; - H5G_loc_t loc; /* File location */ - const char *name; +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rcreate_region() */ - /* Get arguments */ - loc_id = va_arg(ap, hid_t); - name = va_arg(ap, const char *); +/*-------------------------------------------------------------------------- + NAME + H5Rcreate_attr + PURPOSE + Creates a particular kind of reference for the user + USAGE + href_t *H5Rcreate_attr(loc_id, name, attr_name) + hid_t loc_id; IN: Location ID used to locate object pointed to + const char *name; IN: Name of object at location LOC_ID of object + pointed to + const char *attr_name; IN: Name of attribute pointed to, used for + Attribute references. - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") + RETURNS + Reference created on success/NULL on failure + DESCRIPTION + Creates a particular type of reference specified with REF_TYPE, in the + space pointed to by REF. The LOC_ID, NAME and ATTR_NAME are used to locate + the attribute pointed to. +--------------------------------------------------------------------------*/ +href_t * +H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name) +{ + H5G_loc_t loc; /* File location */ + href_t *ret_value = NULL; /* Return value */ - if((ret_value = H5R_create(ref, ref_type, &loc, name, H5AC_dxpl_id)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to create reference") - } - break; - case H5R_REGION: - case H5R_DATASET_REGION: - { - hid_t loc_id; - H5G_loc_t loc; /* File location */ - const char *name; - hid_t space_id; - - /* Get arguments */ - loc_id = va_arg(ap, hid_t); - name = va_arg(ap, const char *); - space_id = va_arg(ap, hid_t); - - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") - if(space_id == H5I_BADID) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "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, FAIL, "not a dataspace") - if((ret_value = H5R_create(ref, ref_type, &loc, name, H5AC_dxpl_id, space)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to create reference") - } - break; - case H5R_ATTR: - { - hid_t loc_id; - H5G_loc_t loc; /* File location */ - const char *name; - const char *attr_name; - - /* Get arguments */ - loc_id = va_arg(ap, hid_t); - name = va_arg(ap, const char *); - attr_name = va_arg(ap, const char *); - - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") - if(!attr_name || !*attr_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name given") - if((ret_value = H5R_create(ref, ref_type, &loc, name, H5AC_dxpl_id, attr_name)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to create reference") - } - break; - case H5R_MAXTYPE: - case H5R_BADTYPE: - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - } + 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(!attr_name || !*attr_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no attribute name given") + + if(NULL == (ret_value = H5R_create_attr(&loc, name, H5AC_dxpl_id, attr_name))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, NULL, "unable to create atribute reference") done: - va_end(ap); + FUNC_LEAVE_API(ret_value) +} /* end H5Rcreate_attr() */ + +/*-------------------------------------------------------------------------- + NAME + H5R_destroy + PURPOSE + Destroy a reference + USAGE + herr_t H5R_destroy(ref) + href_t *ref; IN: Reference + RETURNS + Reference created on success/NULL on failure + DESCRIPTION + Destroy reference and free resources allocated during H5Rcreate. +--------------------------------------------------------------------------*/ +herr_t +H5R_destroy(href_t *ref) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(ref); + + if(H5R_OBJECT != ref->ref_type) + H5MM_free(ref->obj_enc.buf); + H5MM_free(ref); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Rdestroy() */ + +/*-------------------------------------------------------------------------- + NAME + H5Rdestroy + PURPOSE + Destroy a reference + USAGE + herr_t H5Rdestroy(ref) + href_t *ref; IN: Reference + + RETURNS + Reference created on success/NULL on failure + DESCRIPTION + Destroy reference and free resources allocated during H5Rcreate. +--------------------------------------------------------------------------*/ +herr_t +H5Rdestroy(href_t *ref) +{ + herr_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Check args */ + if(NULL == ref) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid reference pointer") + + if(FAIL == (ret_value = H5R_destroy(ref))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to destroy reference") + +done: FUNC_LEAVE_API(ret_value) -} /* end H5Rcreate() */ +} /* end H5Rdestroy() */ /*-------------------------------------------------------------------------- NAME - H5R_dereference + H5R__dereference PURPOSE Opens the HDF5 object referenced. USAGE - hid_t H5R_dereference(ref) + hid_t H5R__dereference(file, oapl_id, dxpl_id, ref, app_ref) H5F_t *file; IN: File the object being dereferenced is within - H5R_type_t ref_type; IN: Type of reference - void *ref; IN: Reference to open. + hid_t oapl_id; IN: Property list of the object being referenced. + hid_t dxpl_id; IN: Property list ID + ref_t *ref; IN: Reference to open + hbool_t app_ref IN: Referenced by application. 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. --------------------------------------------------------------------------*/ hid_t -H5R_dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref, hbool_t app_ref) +H5R__dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, const 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) */ - unsigned rc; /* Reference count of object */ - H5O_type_t obj_type; /* Type of object */ - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + H5O_loc_t oloc; /* Object location */ + H5G_name_t path; /* Path of object */ + H5G_loc_t loc; /* Group location */ + char *filename = NULL; /* Name of the file (for external references) */ + char *attr_name = NULL; /* Name of the attribute (for attribute references) */ + unsigned rc; /* Reference count of object */ + H5O_type_t obj_type; /* Type of object */ + const uint8_t *p = NULL; /* Pointer to OID to store */ + hid_t ret_value = H5I_BADID; /* Return value */ FUNC_ENTER_NOAPI_NOINIT - HDassert(_ref); - HDassert(ref_type > H5R_BADTYPE && ref_type < H5R_MAXTYPE); HDassert(file); + HDassert(ref); + HDassert(ref->ref_type > H5R_BADTYPE && ref->ref_type < H5R_MAXTYPE); /* Initialize the object location */ H5O_loc_reset(&oloc); oloc.file = file; - 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, FAIL, "Undefined reference pointer") - break; - - case H5R_DATASET_REGION: + switch (ref->ref_type) { + case H5R_EXT_OBJECT: + case H5R_EXT_REGION: + case H5R_EXT_ATTR: { - H5HG_t hobjid; /* Heap object ID */ - uint8_t *buf; /* Buffer to store serialized selection in */ - const uint8_t *p; /* Pointer to OID to store */ - - /* 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); + size_t filename_len; /* Length of the file name */ - if(!H5F_addr_defined(hobjid.addr) || hobjid.addr == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer") + /* Get the file name length */ + p = (const uint8_t *)ref->obj_enc.buf; + UINT16DECODE(p, filename_len); + HDassert(filename_len < H5R_MAX_ATTR_REF_NAME_LEN); - /* Get the dataset region from the heap (allocate inside routine) */ - if(NULL == (buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL))) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") + /* Allocate space for the file name */ + if(NULL == (filename = (char *)H5MM_malloc(filename_len + 1))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, FAIL, "memory allocation failed") - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); + /* Get the file name */ + HDmemcpy(filename, p, filename_len); + filename[filename_len] = '\0'; + p += filename_len; + } + break; + case H5R_OBJECT: + case H5R_REGION: + case H5R_ATTR: + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + break; + } - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); - } /* end case */ - break; + switch(ref->ref_type) { + case H5R_OBJECT: + oloc.addr = ref->obj_addr; + if(!H5F_addr_defined(oloc.addr) || oloc.addr == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Undefined reference pointer") + break; + case H5R_EXT_OBJECT: + case H5R_EXT_REGION: case H5R_REGION: { - const hreg_ref_t *ref = (const hreg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ - const uint8_t *p; /* Pointer to OID to store */ - /* Get the object oid for the dataset */ - p = (const uint8_t *)ref->buf; + if (!p) p = (const uint8_t *)ref->obj_enc.buf; H5F_addr_decode(oloc.file, &p, &(oloc.addr)); } /* end case */ break; + case H5R_EXT_ATTR: case H5R_ATTR: { - const hattr_ref_t *ref = (const hattr_ref_t *)_ref; /* Get pointer to correct type of reference struct */ - const uint8_t *p; /* Pointer to OID to store */ size_t attr_name_len; /* Length of the attribute name */ /* Get the object oid for the dataset */ - p = (const uint8_t *)ref->buf; + if (!p) p = (const uint8_t *)ref->obj_enc.buf; H5F_addr_decode(oloc.file, &p, &(oloc.addr)); /* Get the attribute name length */ @@ -748,7 +1035,7 @@ H5R_dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, H5R_type_t ref_type, loc.path = &path; /* Open an attribute */ - if(H5R_ATTR == ref_type) { + if(H5R_ATTR == ref->ref_type || H5R_EXT_ATTR == ref->ref_type) { H5A_t *attr; /* Attribute opened */ /* Open the attribute */ @@ -828,10 +1115,11 @@ H5R_dereference(H5F_t *file, hid_t oapl_id, hid_t dxpl_id, H5R_type_t ref_type, } /* end else */ done: + H5MM_xfree(filename); H5MM_xfree(attr_name); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R_dereference() */ +} /* end H5R__dereference() */ /*-------------------------------------------------------------------------- @@ -840,66 +1128,55 @@ done: PURPOSE Opens the HDF5 object referenced. USAGE - hid_t H5Rdereference2(ref) - hid_t id; IN: Dataset reference object is in or location ID of + hid_t H5Rdereference2(obj_id, oapl_id, ref) + hid_t obj_id; IN: Dataset reference object is in or location ID of object that the dataset is located within. hid_t oapl_id; IN: Property list of the object being referenced. - H5R_type_t ref_type; IN: Type of reference to create - void *ref; IN: Reference to open. + href_t *ref; IN: Reference to open. 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 - 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. --------------------------------------------------------------------------*/ hid_t -H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *_ref) +H5Rdereference2(hid_t obj_id, hid_t oapl_id, const href_t *ref) { H5G_loc_t loc; /* Group location */ hid_t ret_value; FUNC_ENTER_API(FAIL) - H5TRACE4("i", "iiRt*x", obj_id, oapl_id, ref_type, _ref); /* Check args */ if(H5G_loc(obj_id, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(oapl_id < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - if(_ref == NULL) + if(ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(ref->ref_type <= H5R_BADTYPE || ref->ref_type >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") /* Create reference */ - if((ret_value = H5R_dereference(loc.oloc->file, oapl_id, H5AC_ind_dxpl_id, ref_type, _ref, TRUE)) < 0) + 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") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rdereference2() */ +} /* end H5Rdereference2() */ /*-------------------------------------------------------------------------- NAME - H5R_get_region + H5R__get_region PURPOSE Retrieves a dataspace with the region pointed to selected. USAGE - H5S_t *H5R_get_region(file, dxpl_id, ref_type, ref) + H5S_t *H5R__get_region(file, dxpl_id, ref_type, ref) H5F_t *file; IN: File the object being dereferenced is within hid_t dxpl_id; IN: Property list ID - H5R_type_t ref_type; IN: Type of reference to get region of - void *ref; IN: Reference to open. + href_t *ref; IN: Reference to open. RETURNS Pointer to the dataspace on success, NULL on failure @@ -907,46 +1184,43 @@ done: 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 --------------------------------------------------------------------------*/ static H5S_t * -H5R_get_region(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref) +H5R__get_region(H5F_t *file, hid_t dxpl_id, const href_t *ref) { 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 */ + char *filename = NULL; /* Name of the file (for external references) */ H5S_t *ret_value; FUNC_ENTER_NOAPI_NOINIT - HDassert(_ref); HDassert(file); + HDassert(ref); + HDassert((ref->ref_type == H5R_REGION) || (ref->ref_type == H5R_EXT_REGION)); /* Initialize the object location */ H5O_loc_reset(&oloc); oloc.file = file; - if (ref_type == H5R_DATASET_REGION) { - /* 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); + /* Point to reference buffer now */ + p = (const uint8_t *)ref->obj_enc.buf; - /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, NULL, "Unable to read dataset region information") + if (ref->ref_type == H5R_EXT_REGION) { + size_t filename_len; /* Length of the file name */ - /* Point to heap buffer now */ - p = buf; - } else { - const hreg_ref_t *ref = (const hreg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ + /* Get the file name length */ + UINT16DECODE(p, filename_len); + HDassert(filename_len < H5R_MAX_ATTR_REF_NAME_LEN); - /* Point to reference buffer now */ - p = (const uint8_t *)ref->buf; + /* Allocate space for the file name */ + if(NULL == (filename = (char *)H5MM_malloc(filename_len + 1))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, NULL, "memory allocation failed") + + /* Get the file name */ + HDmemcpy(filename, p, filename_len); + filename[filename_len] = '\0'; + p += filename_len; } /* Get the object oid for the dataset */ @@ -961,11 +1235,9 @@ H5R_get_region(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection") done: - /* Free the buffer allocated in H5HG_read() */ - H5MM_free(buf); - + H5MM_xfree(filename); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R_get_region() */ +} /* end H5R__get_region() */ /*-------------------------------------------------------------------------- @@ -974,11 +1246,10 @@ done: PURPOSE Retrieves a dataspace with the region pointed to selected. USAGE - hid_t H5Rget_region(id, ref_type, ref) - hid_t id; IN: Dataset reference object is in or location ID of + hid_t H5Rget_region(loc_id, ref) + hid_t loc_id; IN: Dataset reference object is in or location ID of object that the dataset is located within. - H5R_type_t ref_type; IN: Type of reference to get region of - void *ref; IN: Reference to open. + href_t *ref; IN: Reference to open. RETURNS Valid ID on success, Negative on failure @@ -986,31 +1257,26 @@ done: 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 --------------------------------------------------------------------------*/ hid_t -H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) +H5Rget_region(hid_t loc_id, const href_t *ref) { H5G_loc_t loc; /* Object's group location */ H5S_t *space = NULL; /* Dataspace object */ hid_t ret_value; FUNC_ENTER_API(FAIL) - H5TRACE3("i", "iRt*x", id, ref_type, ref); /* Check args */ - if(H5G_loc(id, &loc) < 0) + if(H5G_loc(loc_id, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(ref_type != H5R_DATASET_REGION && ref_type != H5R_REGION) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") if(ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(ref->ref_type != H5R_REGION && ref->ref_type != H5R_EXT_REGION) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") /* Get the dataspace with the correct region selected */ - if((space = H5R_get_region(loc.oloc->file, H5AC_ind_dxpl_id, ref_type, ref)) == NULL) + if((space = H5R__get_region(loc.oloc->file, H5AC_ind_dxpl_id, ref)) == NULL) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create dataspace") /* Atomize */ @@ -1019,85 +1285,55 @@ H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) done: FUNC_LEAVE_API(ret_value) -} /* end H5Rget_region() */ +} /* end H5Rget_region() */ /*-------------------------------------------------------------------------- NAME - H5R_get_obj_type + 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. + herr_t H5R_get_obj_type(file, dxpl_id, ref, obj_type) + H5F_t *file; IN: File the object being dereferenced is within + hid_t dxpl_id; IN: Property list ID + href_t *ref; IN: Reference to open + H5O_type_t *obj_type OUT: Object type RETURNS - Success: An object type defined in H5Gpublic.h - Failure: H5G_UNKNOWN + 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 --------------------------------------------------------------------------*/ herr_t -H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, - const void *_ref, H5O_type_t *obj_type) +H5R__get_obj_type(H5F_t *file, hid_t dxpl_id, const href_t *ref, H5O_type_t *obj_type) { H5O_loc_t oloc; /* Object location */ - unsigned rc; /* Reference count of object */ + unsigned rc; /* Reference count of object */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT + HDassert(ref); HDassert(file); - HDassert(_ref); /* Initialize the symbol table entry */ H5O_loc_reset(&oloc); oloc.file = file; - switch(ref_type) { + switch(ref->ref_type) { case H5R_OBJECT: /* Get the object oid */ - oloc.addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */ + oloc.addr = ref->obj_addr; break; - 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 */ - - /* 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); - - /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") - - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); - - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); - break; - } /* end case */ - case H5R_REGION: { - const hreg_ref_t *ref = (const hreg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ const uint8_t *p; /* Pointer to reference to decode */ /* Get the object oid for the dataset */ - p = (const uint8_t *)ref->buf; + p = (const uint8_t *)ref->obj_enc.buf; H5F_addr_decode(oloc.file, &p, &(oloc.addr)); break; @@ -1105,11 +1341,10 @@ H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, case H5R_ATTR: { - const hattr_ref_t *ref = (const hattr_ref_t *)_ref; /* Get pointer to correct type of reference struct */ const uint8_t *p; /* Pointer to reference to decode */ /* Get the object oid for the dataset */ - p = (const uint8_t *)ref->buf; + p = (const uint8_t *)ref->obj_enc.buf; H5F_addr_decode(oloc.file, &p, &(oloc.addr)); break; @@ -1129,7 +1364,7 @@ H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R_get_obj_type() */ +} /* end H5R__get_obj_type() */ /*-------------------------------------------------------------------------- @@ -1138,11 +1373,10 @@ done: PURPOSE Retrieves the type of object that an object reference points to USAGE - herr_t H5Rget_obj_type2(id, ref_type, ref, obj_type) - hid_t id; IN: Dataset reference object is in or location ID of + herr_t H5Rget_obj_type2(loc_id, ref, obj_type) + hid_t loc_id; IN: Dataset reference object is in or location ID of object that the dataset is located within. - H5R_type_t ref_type; IN: Type of reference to query - void *ref; IN: Reference to query. + href_t *ref; IN: Reference to query. H5O_type_t *obj_type; OUT: Type of object reference points to RETURNS @@ -1150,52 +1384,45 @@ done: DESCRIPTION Given a reference to some object, this function retrieves the type of object pointed to. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - EXAMPLES - REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, - H5O_type_t *obj_type) +H5Rget_obj_type2(hid_t loc_id, const href_t *ref, H5O_type_t *obj_type) { H5G_loc_t loc; /* Object location */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE4("e", "iRt*x*Ot", id, ref_type, ref, obj_type); /* Check args */ - if(H5G_loc(id, &loc) < 0) + if(H5G_loc(loc_id, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") if(ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(ref->ref_type <= H5R_BADTYPE || ref->ref_type >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") /* Get the object information */ - if(H5R_get_obj_type(loc.oloc->file, H5AC_ind_dxpl_id, ref_type, ref, obj_type) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to determine object type") + if(H5R__get_obj_type(loc.oloc->file, H5AC_ind_dxpl_id, ref, obj_type) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to determine object type") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rget_obj_type2() */ +} /* end H5Rget_obj_type2() */ /*-------------------------------------------------------------------------- NAME - H5R_get_name + H5R__get_name PURPOSE Internal routine to determine a name for the object referenced USAGE - ssize_t H5R_get_name(f, dxpl_id, ref_type, ref, name, size) + ssize_t H5R__get_name(f, lapl_id, dxpl_id, loc_id, 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 dxpl_id; IN: DXPL 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. + hid_t loc_id; IN: Location ID given for reference + href_t *ref; IN: Reference to query. char *name; OUT: Buffer to place name of object referenced size_t size; IN: Size of name buffer @@ -1204,81 +1431,83 @@ done: 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 --------------------------------------------------------------------------*/ static ssize_t -H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_type, - const void *_ref, char *name, size_t size) +H5R__get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t loc_id, const href_t *ref, + char *name, size_t size) { - hid_t file_id = H5I_INVALID_HID; /* ID for file that the reference is in */ + 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 */ + char *filename = NULL; /* Name of the file (for external references) */ + const uint8_t *p; /* Pointer to reference to decode */ FUNC_ENTER_NOAPI_NOINIT /* Check args */ HDassert(f); - HDassert(_ref); + HDassert(ref); /* Initialize the object location */ H5O_loc_reset(&oloc); oloc.file = f; - /* Get address for reference */ - switch(ref_type) { - case H5R_OBJECT: - oloc.addr = *(const hobj_ref_t *)_ref; - break; - - case H5R_DATASET_REGION: + switch (ref->ref_type) { + case H5R_EXT_OBJECT: + case H5R_EXT_REGION: + case H5R_EXT_ATTR: { - H5HG_t hobjid; /* Heap object ID */ - uint8_t *buf; /* Buffer to store serialized selection in */ - const uint8_t *p; /* Pointer to OID to store */ + size_t filename_len; /* Length of the file name */ - /* 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); + /* Get the file name length */ + p = (const uint8_t *)ref->obj_enc.buf; + UINT16DECODE(p, filename_len); + HDassert(filename_len < H5R_MAX_ATTR_REF_NAME_LEN); - /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = (uint8_t *)H5HG_read(oloc.file, dxpl_id, &hobjid, NULL, NULL)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") + /* Allocate space for the file name */ + if(NULL == (filename = (char *)H5MM_malloc(filename_len + 1))) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, FAIL, "memory allocation failed") - /* Get the object oid for the dataset */ - p = buf; - H5F_addr_decode(oloc.file, &p, &(oloc.addr)); + /* Get the file name */ + HDmemcpy(filename, p, filename_len); + filename[filename_len] = '\0'; + p += filename_len; + } + break; + case H5R_OBJECT: + case H5R_REGION: + case H5R_ATTR: + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + break; + } - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); - } /* end case */ - break; + /* Get address for reference */ + switch(ref->ref_type) { + case H5R_OBJECT: + oloc.addr = ref->obj_addr; + break; + case H5R_EXT_OBJECT: + case H5R_EXT_REGION: case H5R_REGION: { - const hreg_ref_t *ref = (const hreg_ref_t *)_ref; /* Get pointer to correct type of reference struct */ - const uint8_t *p; /* Pointer to reference to decode */ - /* Get the object oid for the dataset */ - p = (const uint8_t *)ref->buf; + if (!p) p = (const uint8_t *)ref->obj_enc.buf; H5F_addr_decode(oloc.file, &p, &(oloc.addr)); } /* end case */ break; + case H5R_EXT_ATTR: case H5R_ATTR: { - const hattr_ref_t *ref = (const hattr_ref_t *)_ref; /* Get pointer to correct type of reference struct */ - const uint8_t *p; /* Pointer to OID to store */ size_t attr_name_len; /* Length of the attribute name */ size_t copy_len; /* Get the object oid for the dataset */ - p = (const uint8_t *)ref->buf; + if (!p) p = (const uint8_t *)ref->obj_enc.buf; H5F_addr_decode(oloc.file, &p, &(oloc.addr)); /* Get the attribute name length */ @@ -1301,9 +1530,9 @@ H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_ty HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") } /* end switch */ - if (ref_type != H5R_ATTR) { + if (ref->ref_type != H5R_ATTR && ref->ref_type != H5R_EXT_ATTR) { /* Retrieve file ID for name search */ - if((file_id = H5I_get_file_id(id, FALSE)) < 0) + 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. */ @@ -1315,9 +1544,9 @@ done: /* Close file ID used for search */ if(file_id > 0 && H5I_dec_ref(file_id) < 0) HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "can't decrement ref count of temp ID") - + H5MM_xfree(filename); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5R_get_name() */ +} /* end H5R__get_name() */ /*-------------------------------------------------------------------------- @@ -1326,11 +1555,10 @@ done: PURPOSE Determines a name for the object referenced USAGE - ssize_t H5Rget_name(loc_id, ref_type, ref, name, size) + ssize_t H5Rget_name(loc_id, ref, name, size) hid_t loc_id; IN: Dataset reference object is in or location ID of object that the dataset is located within. - H5R_type_t ref_type; IN: Type of reference - void *ref; IN: Reference to query. + href_t *ref; IN: Reference to query. char *name; OUT: Buffer to place name of object referenced. If NULL then this call will return the size in bytes of name. size_t size; IN: Size of name buffer (user needs to include NULL terminator @@ -1341,45 +1569,137 @@ done: 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 - M. Scot Breitenfeld - 22 January 2014 - Changed the behavior for the returned value of the function when name is NULL. - If name is NULL then size is ignored and the function returns the size - of the name buffer (not including the NULL terminator), it still returns - negative on failure. --------------------------------------------------------------------------*/ ssize_t -H5Rget_name(hid_t id, H5R_type_t ref_type, const void *_ref, char *name, - size_t size) +H5Rget_name(hid_t loc_id, const href_t *ref, char *name, size_t size) { H5G_loc_t loc; /* Group location */ H5F_t *file; /* File object */ ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE5("Zs", "iRt*x*sz", id, ref_type, _ref, name, size); /* Check args */ - if(H5G_loc(id, &loc) < 0) + if(H5G_loc(loc_id, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - if(_ref == NULL) + if(ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(ref->ref_type <= H5R_BADTYPE || ref->ref_type >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") /* Get the file pointer from the entry */ file = loc.oloc->file; /* Get name */ - if((ret_value = H5R_get_name(file, H5P_DEFAULT, H5AC_ind_dxpl_id, id, ref_type, _ref, name, size)) < 0) + if((ret_value = H5R__get_name(file, H5P_DEFAULT, H5AC_ind_dxpl_id, loc_id, ref, name, size)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to determine object path") done: FUNC_LEAVE_API(ret_value) } /* end H5Rget_name() */ +/*-------------------------------------------------------------------------- + NAME + H5R__get_filename + PURPOSE + Determines a file name for the object referenced + USAGE + ssize_t H5R__get_filename(ref, name, size) + href_t *ref; IN: Reference to query. + char *name; OUT: Buffer to place file name of object referenced. If NULL + then this call will return the size in bytes of name. + size_t size; IN: Size of name buffer (user needs to include NULL terminator + when passing in the size) + + RETURNS + Non-negative length of the path on success, Negative on failure + DESCRIPTION + Given a reference to some object, determine a file name to the object + referenced. +--------------------------------------------------------------------------*/ +static ssize_t +H5R__get_filename(const href_t *ref, char *name, size_t size) +{ + ssize_t ret_value = -1; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + HDassert(ref); + + switch (ref->ref_type) { + 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 copy_len; + + /* Get the file name length */ + p = (const uint8_t *)ref->obj_enc.buf; + UINT16DECODE(p, filename_len); + copy_len = MIN(filename_len, size - 1); + + /* Get the attribute name */ + if (name) { + HDmemcpy(name, p, copy_len); + name[copy_len] = '\0'; + } + ret_value = (ssize_t)copy_len; + } + break; + case H5R_OBJECT: + case H5R_REGION: + case H5R_ATTR: + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + HDassert("unknown reference type" && 0); + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") + break; + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5R__get_filename() */ + +/*-------------------------------------------------------------------------- + NAME + H5Rget_filename + PURPOSE + Determines a file name for the object referenced + USAGE + ssize_t H5Rget_filename(ref, name, size) + href_t *ref; IN: Reference to query. + char *name; OUT: Buffer to place file name of object referenced. If NULL + then this call will return the size in bytes of name. + size_t size; IN: Size of name buffer (user needs to include NULL terminator + when passing in the size) + + RETURNS + Non-negative length of the path on success, Negative on failure + DESCRIPTION + Given a reference to some object, determine a file name to the object + referenced. +--------------------------------------------------------------------------*/ +ssize_t +H5Rget_filename(const href_t *ref, char *name, size_t size) +{ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + + /* Check args */ + if(ref == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") + if(ref->ref_type <= H5R_BADTYPE || ref->ref_type >= H5R_MAXTYPE) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + + /* Get name */ + if((ret_value = H5R__get_filename(ref, name, size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to retrieve file name") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Rget_filename() */ diff --git a/src/H5Rdeprec.c b/src/H5Rdeprec.c index b8133b2..05cfb71 100644 --- a/src/H5Rdeprec.c +++ b/src/H5Rdeprec.c @@ -125,7 +125,7 @@ H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference pointer") /* Get the object information */ - if(H5R_get_obj_type(loc.oloc->file, H5AC_ind_dxpl_id, ref_type, ref, &obj_type) < 0) + if(H5R__get_obj_type(loc.oloc->file, H5AC_ind_dxpl_id, ref, &obj_type) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type") /* Set return value */ @@ -133,7 +133,7 @@ H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref) done: FUNC_LEAVE_API(ret_value) -} /* end H5Rget_obj_type1() */ +} /* end H5Rget_obj_type1() */ /*-------------------------------------------------------------------------- @@ -159,7 +159,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ hid_t -H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *_ref) +H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *ref) { H5G_loc_t loc; /* Group location */ H5F_t *file = NULL; /* File object */ @@ -173,19 +173,19 @@ H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *_ref) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - if(_ref == NULL) + if(ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") /* Get the file pointer from the entry */ file = loc.oloc->file; /* Create reference */ - if((ret_value = H5R_dereference(file, H5P_DATASET_ACCESS_DEFAULT, H5AC_ind_dxpl_id, ref_type, _ref, TRUE)) < 0) + if((ret_value = H5R__dereference(file, H5P_DATASET_ACCESS_DEFAULT, H5AC_ind_dxpl_id, ref, TRUE)) < 0) HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable dereference object") done: FUNC_LEAVE_API(ret_value) -} /* end H5Rdereference1() */ +} /* end H5Rdereference1() */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Rpkg.h b/src/H5Rpkg.h index 8ed8d65..bc9d933 100644 --- a/src/H5Rpkg.h +++ b/src/H5Rpkg.h @@ -54,10 +54,10 @@ /******************************/ /* General functions */ -H5_DLL herr_t H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, - const void *_ref, H5O_type_t *obj_type); -H5_DLL hid_t H5R_dereference(H5F_t *file, hid_t dapl_id, hid_t dxpl_id, H5R_type_t ref_type, - const void *_ref, hbool_t app_ref); +H5_DLL herr_t H5R__get_obj_type(H5F_t *file, hid_t dxpl_id, const href_t *ref, + H5O_type_t *obj_type); +H5_DLL hid_t H5R__dereference(H5F_t *file, hid_t dapl_id, hid_t dxpl_id, + const href_t *ref, hbool_t app_ref); #endif /* _H5Rpkg_H */ diff --git a/src/H5Rprivate.h b/src/H5Rprivate.h index ba19c8b..bc51b21 100644 --- a/src/H5Rprivate.h +++ b/src/H5Rprivate.h @@ -26,9 +26,29 @@ #include "H5Gprivate.h" /* Internal data structures */ +struct href_t { + H5R_type_t ref_type; + union { + struct { + size_t buf_size;/* Size of serialized reference */ + void *buf; /* Pointer to serialized reference */ + } obj_enc; + haddr_t obj_addr; + }; +}; + +#define H5R_INITIALIZER { H5R_BADTYPE, {0, NULL} } + +/* To prevent including H5Sprivate.h that includes H5Rprivate.h */ +struct H5S_t; /* Private functions */ -H5_DLL herr_t H5R_create(void *ref, H5R_type_t ref_type, ...); +H5_DLL href_t *H5R_create_object(H5G_loc_t *loc, const char *name, hid_t dxpl_id); +H5_DLL href_t *H5R_create_region(H5G_loc_t *loc, const char *name, hid_t dxpl_id, struct H5S_t *space); +H5_DLL href_t *H5R_create_attr(H5G_loc_t *loc, const char *name, hid_t dxpl_id, const char *attr_name); +H5_DLL href_t *H5R_create_ext_object(H5G_loc_t *loc, const char *name, hid_t dxpl_id); +H5_DLL href_t *H5R_create_ext_region(H5G_loc_t *loc, const char *name, hid_t dxpl_id, struct H5S_t *space); +H5_DLL href_t *H5R_create_ext_attr(H5G_loc_t *loc, const char *name, hid_t dxpl_id, const char *attr_name); +H5_DLL herr_t H5R_destroy(href_t *ref); #endif /* _H5Rprivate_H */ - diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index 580a5d3..f792202 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -30,43 +30,16 @@ typedef enum { H5R_BADTYPE = (-1), /*invalid Reference Type */ H5R_OBJECT, /*Object reference */ - H5R_DATASET_REGION, /*Dataset Region Reference */ - H5R_REGION, /*Revised Dataset Region Reference */ + H5R_REGION, /*Dataset Region Reference */ H5R_ATTR, /*Attribute Reference */ - H5R_MAXTYPE /*highest type (Invalid as true type) */ + H5R_EXT_OBJECT, /*External Object reference */ + H5R_EXT_REGION, /*External Region reference */ + H5R_EXT_ATTR, /*External Attribute reference */ + H5R_MAXTYPE /*highest type (Invalid as true type) */ } H5R_type_t; -/* Note! Be careful with the sizes of the references because they should really - * depend on the run-time values in the file. Unfortunately, the arrays need - * to be defined at compile-time, so we have to go with the worst case sizes for - * them. -QAK - */ -#define H5R_OBJ_REF_BUF_SIZE sizeof(haddr_t) -/* Object reference structure for user's code */ -typedef haddr_t hobj_ref_t; /* Needs to be large enough to store largest haddr_t in a worst case machine (ie. 8 bytes currently) */ - -#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(haddr_t)+4) -/* 4 is used instead of sizeof(int) to permit portability between - the Crays and other machines (the heap ID is always encoded as an int32 anyway) -*/ -/* Dataset Region reference structure for user's code */ -typedef unsigned char hdset_reg_ref_t[H5R_DSET_REG_REF_BUF_SIZE];/* Buffer to store heap ID and index */ -/* Needs to be large enough to store largest haddr_t in a worst case machine (ie. 8 bytes currently) plus an int */ - -/* Variable length reference struct in memory */ -struct href_var { - size_t buf_size;/* Size of serialized reference */ - void *buf; /* Pointer to serialized reference */ -}; - -typedef struct href_var hreg_ref_t; - -#define H5R_REG_REF_INITIALIZER { 0, NULL } - -/* Attribute reference structure for user's code (variable length) */ -typedef struct href_var hattr_ref_t; - -#define H5R_ATTR_REF_INITIALIZER { 0, NULL } +/* Opaque reference type */ +typedef struct href_t href_t; /* Publicly visible data structures */ @@ -75,13 +48,19 @@ extern "C" { #endif /* Functions in H5R.c */ -H5_DLL herr_t H5Rcreate(void *ref, H5R_type_t ref_type, ...); -H5_DLL hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *ref); -H5_DLL hid_t H5Rget_region(hid_t dataset, H5R_type_t ref_type, const void *ref); -H5_DLL herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *_ref, - H5O_type_t *obj_type); -H5_DLL ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref, - char *name/*out*/, size_t size); +H5_DLL href_t *H5Rcreate_object(hid_t loc_id, const char *name); +H5_DLL href_t *H5Rcreate_region(hid_t loc_id, const char *name, hid_t space_id); +H5_DLL href_t *H5Rcreate_attr(hid_t loc_id, const char *name, const char *attr_name); +H5_DLL href_t *H5Rcreate_ext_object(hid_t loc_id, const char *name); +H5_DLL href_t *H5Rcreate_ext_region(hid_t loc_id, const char *name, hid_t space_id); +H5_DLL href_t *H5Rcreate_ext_attr(hid_t loc_id, const char *name, const char *attr_name); +H5_DLL herr_t H5Rdestroy(href_t *ref); + +H5_DLL hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, const href_t *ref); +H5_DLL hid_t H5Rget_region(hid_t loc_id, const href_t *ref); +H5_DLL herr_t H5Rget_obj_type2(hid_t loc_id, const href_t *ref, H5O_type_t *obj_type); +H5_DLL ssize_t H5Rget_name(hid_t loc_id, const href_t *ref, char *name/*out*/, size_t size); +H5_DLL ssize_t H5Rget_filename(const href_t *ref, char *name/*out*/, size_t size); /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -96,6 +75,7 @@ H5_DLL ssize_t H5Rget_name(hid_t loc_id, H5R_type_t ref_type, const void *ref, /* Function prototypes */ +/* TODO should add a H5Rcreate1 that maps to other types */ H5_DLL H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *_ref); H5_DLL hid_t H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *ref); @@ -218,32 +218,38 @@ #define H5T_INIT_TYPE_REF_COMMON { \ H5T_INIT_TYPE_ALLOC_COMMON(H5T_REFERENCE) \ H5T_INIT_TYPE_NUM_COMMON(H5T_ORDER_NONE) \ + dt->shared->force_conv = TRUE; \ + dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; \ } #define H5T_INIT_TYPE_OBJREF_CORE { \ H5T_INIT_TYPE_REF_COMMON \ - dt->shared->force_conv = TRUE; \ dt->shared->u.atomic.u.r.rtype = H5R_OBJECT; \ - dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY; \ } -#define H5T_INIT_TYPE_DSET_REGREF_CORE { \ +#define H5T_INIT_TYPE_REGREF_CORE { \ H5T_INIT_TYPE_REF_COMMON \ - dt->shared->u.atomic.u.r.rtype = H5R_DATASET_REGION; \ + dt->shared->u.atomic.u.r.rtype = H5R_REGION; \ } -#define H5T_INIT_TYPE_REGREF_CORE { \ - H5T_INIT_TYPE_REF_COMMON \ - dt->shared->force_conv = TRUE; \ - dt->shared->u.atomic.u.r.rtype = H5R_REGION; \ - dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; \ +#define H5T_INIT_TYPE_ATTRREF_CORE { \ + H5T_INIT_TYPE_REF_COMMON \ + dt->shared->u.atomic.u.r.rtype = H5R_ATTR; \ } -#define H5T_INIT_TYPE_ATTRREF_CORE { \ - H5T_INIT_TYPE_REF_COMMON \ - dt->shared->force_conv = TRUE; \ - dt->shared->u.atomic.u.r.rtype = H5R_ATTR; \ - dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; \ +#define H5T_INIT_TYPE_EXTOBJREF_CORE { \ + H5T_INIT_TYPE_REF_COMMON \ + dt->shared->u.atomic.u.r.rtype = H5R_EXT_OBJECT; \ +} + +#define H5T_INIT_TYPE_EXTREGREF_CORE { \ + H5T_INIT_TYPE_REF_COMMON \ + dt->shared->u.atomic.u.r.rtype = H5R_EXT_REGION; \ +} + +#define H5T_INIT_TYPE_EXTATTRREF_CORE { \ + H5T_INIT_TYPE_REF_COMMON \ + dt->shared->u.atomic.u.r.rtype = H5R_EXT_ATTR; \ } /* Define the code templates for the "SIZE_TMPL" in the H5T_INIT_TYPE macro */ @@ -356,10 +362,12 @@ hid_t H5T_STD_B32BE_g = FAIL; hid_t H5T_STD_B32LE_g = FAIL; hid_t H5T_STD_B64BE_g = FAIL; hid_t H5T_STD_B64LE_g = FAIL; -hid_t H5T_STD_REF_OBJ_g = FAIL; -hid_t H5T_STD_REF_DSETREG_g = FAIL; -hid_t H5T_STD_REF_REG_g = FAIL; -hid_t H5T_STD_REF_ATTR_g = FAIL; +hid_t H5T_STD_REF_OBJ_g = FAIL; +hid_t H5T_STD_REF_REG_g = FAIL; +hid_t H5T_STD_REF_ATTR_g = FAIL; +hid_t H5T_STD_REF_EXT_OBJ_g = FAIL; +hid_t H5T_STD_REF_EXT_REG_g = FAIL; +hid_t H5T_STD_REF_EXT_ATTR_g = FAIL; hid_t H5T_UNIX_D32BE_g = FAIL; hid_t H5T_UNIX_D32LE_g = FAIL; @@ -448,10 +456,7 @@ size_t H5T_NATIVE_LDOUBLE_COMP_ALIGN_g = 0; size_t H5T_POINTER_COMP_ALIGN_g = 0; size_t H5T_HVL_COMP_ALIGN_g = 0; -size_t H5T_HOBJREF_COMP_ALIGN_g = 0; -size_t H5T_HDSETREGREF_COMP_ALIGN_g = 0; -size_t H5T_HREGREF_COMP_ALIGN_g = 0; -size_t H5T_HATTRREF_COMP_ALIGN_g = 0; +size_t H5T_HREF_COMP_ALIGN_g = 0; /* * Alignment constraints for native types. These are initialized at run time @@ -739,6 +744,9 @@ H5T__init_package(void) H5T_t *objref=NULL; /* Datatype structure for object reference objects */ H5T_t *regref=NULL; /* Datatype structure for region reference objects */ H5T_t *attrref=NULL; /* Datatype structure for attribute reference objects */ + H5T_t *extobjref=NULL; /* Datatype structure for external object reference objects */ + H5T_t *extregref=NULL; /* Datatype structure for external region reference objects */ + H5T_t *extattrref=NULL; /* Datatype structure for external attribute reference objects */ hsize_t dim[1]={1}; /* Dimension info for array datatype */ herr_t status; unsigned copied_dtype=1; /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */ @@ -991,26 +999,41 @@ H5T__init_package(void) */ /* Object reference (i.e. object header address in file) */ - H5T_INIT_TYPE(OBJREF, H5T_STD_REF_OBJ_g, ALLOC, -, SET, H5R_OBJ_REF_BUF_SIZE) + H5T_INIT_TYPE(OBJREF, H5T_STD_REF_OBJ_g, ALLOC, -, NOSET, -) + if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") objref = dt; /* Keep type for later */ /* Dataset Region reference (i.e. selection inside a dataset) */ - H5T_INIT_TYPE(DSET_REGREF, H5T_STD_REF_DSETREG_g, ALLOC, -, SET, H5R_DSET_REG_REF_BUF_SIZE) - - /* Dataset Region reference (i.e. selection inside a dataset) */ H5T_INIT_TYPE(REGREF, H5T_STD_REF_REG_g, ALLOC, -, NOSET, -) - /* TODO put that in the macro */ if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") regref = dt; /* Keep type for later */ /* Attribute reference (i.e. object and attribute names in file) */ H5T_INIT_TYPE(ATTRREF, H5T_STD_REF_ATTR_g, ALLOC, -, NOSET, -) - /* TODO put that in the macro */ if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") attrref = dt; /* Keep type for later */ + /* Object reference (i.e. object header address in file) */ + H5T_INIT_TYPE(EXTOBJREF, H5T_STD_REF_EXT_OBJ_g, ALLOC, -, NOSET, -) + if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + extobjref = dt; /* Keep type for later */ + + /* Dataset Region reference (i.e. selection inside a dataset) */ + H5T_INIT_TYPE(EXTREGREF, H5T_STD_REF_EXT_REG_g, ALLOC, -, NOSET, -) + if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + extregref = dt; /* Keep type for later */ + + /* Attribute reference (i.e. object and attribute names in file) */ + H5T_INIT_TYPE(EXTATTRREF, H5T_STD_REF_EXT_ATTR_g, ALLOC, -, NOSET, -) + if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + extattrref = dt; /* Keep type for later */ + /* * Register conversion functions beginning with the most general and * ending with the most specific. @@ -1044,7 +1067,7 @@ H5T__init_package(void) status |= H5T_register(H5T_PERS_SOFT, "enum_f", enum_type, floatpt, H5T__conv_enum_numeric, H5AC_ind_dxpl_id, FALSE); status |= H5T_register(H5T_PERS_SOFT, "vlen", vlen, vlen, H5T__conv_vlen, H5AC_ind_dxpl_id, FALSE); status |= H5T_register(H5T_PERS_SOFT, "array", array, array, H5T__conv_array, H5AC_ind_dxpl_id, FALSE); - status |= H5T_register(H5T_PERS_SOFT, "objref", objref, objref, H5T__conv_order_opt, H5AC_ind_dxpl_id, FALSE); + status |= H5T_register(H5T_PERS_SOFT, "objref", objref, objref, H5T__conv_ref, H5AC_ind_dxpl_id, FALSE); status |= H5T_register(H5T_PERS_SOFT, "regref", regref, regref, H5T__conv_ref, H5AC_ind_dxpl_id, FALSE); status |= H5T_register(H5T_PERS_SOFT, "attrref", attrref, attrref, H5T__conv_ref, H5AC_ind_dxpl_id, FALSE); @@ -1475,8 +1498,7 @@ H5T_top_term_package(void) H5T_STD_B32LE_g = FAIL; H5T_STD_B64BE_g = FAIL; H5T_STD_B64LE_g = FAIL; - H5T_STD_REF_OBJ_g = FAIL; - H5T_STD_REF_DSETREG_g = FAIL; + H5T_STD_REF_OBJ_g = FAIL; H5T_STD_REF_REG_g = FAIL; H5T_STD_REF_ATTR_g = FAIL; @@ -4357,11 +4379,6 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset) HGOTO_DONE(1); break; - case H5R_DATASET_REGION: - /* Does this need more to distinguish it? -QAK 11/30/98 */ - /*void */ - break; - case H5R_REGION: if (dt1->shared->u.atomic.u.r.loc < dt2->shared->u.atomic.u.r.loc) HGOTO_DONE(-1); @@ -4369,8 +4386,23 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset) HGOTO_DONE(1); break; - case H5R_ATTR: - /* Does this need more to distinguish it? -QAK 8/25/15 */ + case H5R_ATTR: + /* Does this need more to distinguish it? -QAK 8/25/15 */ + /*void */ + break; + + case H5R_EXT_OBJECT: + /* Does this need more to distinguish it? -QAK 8/25/15 */ + /*void */ + break; + + case H5R_EXT_REGION: + /* Does this need more to distinguish it? -QAK 8/25/15 */ + /*void */ + break; + + case H5R_EXT_ATTR: + /* Does this need more to distinguish it? -QAK 8/25/15 */ /*void */ break; @@ -5288,25 +5320,11 @@ H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc) break; case H5T_REFERENCE: - /* Only need to change location of object references */ - if(dt->shared->u.atomic.u.r.rtype==H5R_OBJECT) { - /* Mark this reference */ - if(loc!=dt->shared->u.atomic.u.r.loc) { - /* Set the location */ - dt->shared->u.atomic.u.r.loc = loc; - - /* Indicate that the location changed */ - ret_value=TRUE; - } /* end if */ - } /* end if */ - if((dt->shared->u.atomic.u.r.rtype == H5R_REGION) || - (dt->shared->u.atomic.u.r.rtype == H5R_ATTR)) { - /* Mark this reference */ - if((changed = H5T__ref_set_loc(dt, f, loc)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set reference location"); - if(changed > 0) - ret_value = changed; - } + /* Mark this reference */ + if((changed = H5T__ref_set_loc(dt, f, loc)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set reference location"); + if(changed > 0) + ret_value = changed; break; case H5T_NO_CLASS: diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 534ab99..4f6d02f 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -3584,6 +3584,7 @@ H5T__conv_ref(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, uint8_t *b = NULL; /* background buffer */ ssize_t s_stride, d_stride; /* src and dst strides */ ssize_t b_stride; /* bkg stride */ + size_t safe; /* how many elements are safe to process in each pass */ void *conv_buf = NULL; /* temporary conversion buffer */ size_t conv_buf_size = 0; /* size of conversion buffer in bytes */ size_t elmtno; /* element number counter */ @@ -3616,13 +3617,16 @@ H5T__conv_ref(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: { + H5R_type_t ref_type; + /* * Conversion. */ if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - if (src->shared->u.atomic.u.r.rtype == H5R_OBJECT) break; + /* Set reference type */ + ref_type = src->shared->u.atomic.u.r.rtype; /* Initialize source & destination strides */ if(buf_stride) { @@ -3646,36 +3650,78 @@ H5T__conv_ref(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, else b_stride = 0; - /* Single forward pass over all data */ - s = d = (uint8_t *)buf; - b = (uint8_t *)bkg; + /* The outer loop of the type conversion macro, controlling which */ + /* direction the buffer is walked */ + while(nelmts > 0) { + /* Check if we need to go backwards through the buffer */ + if(d_stride > s_stride) { + /* Sanity check */ + HDassert(s_stride > 0); + HDassert(d_stride > 0); + HDassert(b_stride >= 0); - for(elmtno = 0; elmtno < nelmts; elmtno++) { - size_t buf_size; + /* Compute the number of "safe" destination elements at */ + /* the end of the buffer (Those which don't overlap with */ + /* any source elements at the beginning of the buffer) */ + safe = nelmts - (((nelmts * (size_t)s_stride) + ((size_t)d_stride - 1)) / (size_t)d_stride); - /* Get size of references */ - if(0 == (buf_size = (*(src->shared->u.atomic.u.r.getsize))(s))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect length") + /* If we're down to the last few elements, just wrap up */ + /* with a "real" reverse copy */ + if(safe < 2) { + s = (uint8_t *)buf + (nelmts - 1) * (size_t)s_stride; + d = (uint8_t *)buf + (nelmts - 1) * (size_t)d_stride; + b = (uint8_t *)bkg + (nelmts - 1) * (size_t)b_stride; + s_stride = -s_stride; + d_stride = -d_stride; + b_stride = -b_stride; - /* Check if conversion buffer is large enough, resize if necessary. */ - conv_buf_size = buf_size; - if(NULL == (conv_buf = H5FL_BLK_REALLOC(ref_seq, conv_buf, conv_buf_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion") - HDmemset(conv_buf, 0, conv_buf_size); + safe = nelmts; + } /* end if */ + else { + s = (uint8_t *)buf + (nelmts - safe) * (size_t)s_stride; + d = (uint8_t *)buf + (nelmts - safe) * (size_t)d_stride; + b = (uint8_t *)bkg + (nelmts - safe) * (size_t)b_stride; + } /* end else */ + } /* end if */ + else { + /* Single forward pass over all data */ + s = d = (uint8_t *)buf; + b = (uint8_t *)bkg; + safe = nelmts; + } /* end else */ - /* Read reference */ - if((*(src->shared->u.atomic.u.r.read))(src->shared->u.atomic.u.r.f, dxpl_id, s, conv_buf, buf_size) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read reference data") + for(elmtno = 0; elmtno < safe; elmtno++) { + size_t buf_size; + + /* Get size of references */ + if(0 == (buf_size = (*(src->shared->u.atomic.u.r.getsize))(s))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect size") + + /* Check if conversion buffer is large enough, resize if necessary. */ + if(conv_buf_size < buf_size) { + conv_buf_size = buf_size; + if(NULL == (conv_buf = H5FL_BLK_REALLOC(ref_seq, conv_buf, conv_buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion") + HDmemset(conv_buf, 0, conv_buf_size); + } /* end if */ - /* Write reference to destination location */ - if((*(dst->shared->u.atomic.u.r.write))(dst->shared->u.atomic.u.r.f, dxpl_id, d, conv_buf, b, buf_size) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write reference data") + /* Read reference */ + if((*(src->shared->u.atomic.u.r.read))(src->shared->u.atomic.u.r.f, dxpl_id, s, conv_buf, buf_size) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read reference data") - /* Advance pointers */ - s += s_stride; - d += d_stride; - b += b_stride; - } /* end for */ + /* Write reference to destination location */ + if((*(dst->shared->u.atomic.u.r.write))(dst->shared->u.atomic.u.r.f, dxpl_id, d, conv_buf, b, buf_size, ref_type) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write reference data") + + /* Advance pointers */ + s += s_stride; + d += d_stride; + b += b_stride; + } /* end for */ + + /* Decrement number of elements left to convert */ + nelmts -= safe; + } /* end while */ } /* end case */ break; diff --git a/src/H5Tnative.c b/src/H5Tnative.c index 7f536cf..abf36eb 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -124,7 +124,6 @@ done: H5T_t * H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size) { - H5T_t *dt; /* Datatype to make native */ H5T_t *super_type; /* Super type of VL, array and enum datatypes */ H5T_t *nat_super_type; /* Native form of VL, array & enum super datatype */ H5T_t *new_type = NULL; /* New native datatype */ @@ -216,53 +215,11 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig case H5T_REFERENCE: { - size_t align; - size_t ref_size; - int not_equal; - if(NULL == (ret_value = H5T_copy(dtype, H5T_COPY_TRANSIENT))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type") - - /* Decide if the datatype is an object reference. */ - if(NULL == (dt = (H5T_t *)H5I_object(H5T_STD_REF_OBJ_g))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a datatype") - not_equal = H5T_cmp(ret_value, dt, FALSE); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot copy reference type") /* Update size, offset and compound alignment for parent. */ - if(!not_equal) { - align = H5T_HOBJREF_COMP_ALIGN_g; - ref_size = sizeof(hobj_ref_t); - } /* end if */ - else { - /* Decide if the datatype is a dataset region reference. */ - if(NULL == (dt = (H5T_t *)H5I_object(H5T_STD_REF_DSETREG_g))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a datatype") - not_equal = H5T_cmp(ret_value, dt, FALSE); - - /* Update size, offset and compound alignment for parent. */ - if(!not_equal) { - align = H5T_HDSETREGREF_COMP_ALIGN_g; - ref_size = sizeof(hdset_reg_ref_t); - } /* end if */ - else { - /* Decide if the datatype is a dataset region reference. */ - if(NULL == (dt = (H5T_t *)H5I_object(H5T_STD_REF_REG_g))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a datatype") - not_equal = H5T_cmp(ret_value, dt, FALSE); - - /* Update size, offset and compound alignment for parent. */ - if(!not_equal) { - align = H5T_HREGREF_COMP_ALIGN_g; - ref_size = sizeof(hreg_ref_t); - } /* end if */ - else { - align = H5T_HATTRREF_COMP_ALIGN_g; - ref_size = sizeof(hattr_ref_t); - } /* end else */ - } /* end else */ - } /* end else */ - - if(H5T_cmp_offset(comp_size, offset, ref_size, (size_t)1, align, struct_align) < 0) + if(H5T_cmp_offset(comp_size, offset, sizeof(href_t), (size_t)1, H5T_HREF_COMP_ALIGN_g, struct_align) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") } /* end case */ break; diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index fdc3dd7..e7925b8 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -169,7 +169,7 @@ typedef size_t (*H5T_ref_getsizefunc_t)(const void *_ref); typedef herr_t (*H5T_ref_readfunc_t)(H5F_t *f, hid_t dxpl_id, void *_ref, void *buf, size_t buf_size); typedef herr_t (*H5T_ref_writefunc_t)(H5F_t *f, hid_t dxpl_id, void *_ref, - void *buf, void *_bg, size_t buf_size); + void *buf, void *_bg, size_t buf_size, H5R_type_t ref_type); typedef struct H5T_atomic_t { H5T_order_t order; /*byte order */ @@ -365,10 +365,7 @@ H5_DLLVAR size_t H5T_NATIVE_LDOUBLE_COMP_ALIGN_g; H5_DLLVAR size_t H5T_POINTER_COMP_ALIGN_g; H5_DLLVAR size_t H5T_HVL_COMP_ALIGN_g; -H5_DLLVAR size_t H5T_HOBJREF_COMP_ALIGN_g; -H5_DLLVAR size_t H5T_HDSETREGREF_COMP_ALIGN_g; -H5_DLLVAR size_t H5T_HREGREF_COMP_ALIGN_g; -H5_DLLVAR size_t H5T_HATTRREF_COMP_ALIGN_g; +H5_DLLVAR size_t H5T_HREF_COMP_ALIGN_g; /* * Alignment information for native types. A value of N indicates that the diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index f27025c..bcbb518 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -265,9 +265,11 @@ H5_DLLVAR hid_t H5T_IEEE_F64LE_g; #define H5T_STD_B64BE (H5OPEN H5T_STD_B64BE_g) #define H5T_STD_B64LE (H5OPEN H5T_STD_B64LE_g) #define H5T_STD_REF_OBJ (H5OPEN H5T_STD_REF_OBJ_g) -#define H5T_STD_REF_DSETREG (H5OPEN H5T_STD_REF_DSETREG_g) #define H5T_STD_REF_REG (H5OPEN H5T_STD_REF_REG_g) #define H5T_STD_REF_ATTR (H5OPEN H5T_STD_REF_ATTR_g) +#define H5T_STD_REF_EXT_OBJ (H5OPEN H5T_STD_REF_EXT_OBJ_g) +#define H5T_STD_REF_EXT_REG (H5OPEN H5T_STD_REF_EXT_REG_g) +#define H5T_STD_REF_EXT_ATTR (H5OPEN H5T_STD_REF_EXT_ATTR_g) H5_DLLVAR hid_t H5T_STD_I8BE_g; H5_DLLVAR hid_t H5T_STD_I8LE_g; H5_DLLVAR hid_t H5T_STD_I16BE_g; @@ -293,9 +295,11 @@ H5_DLLVAR hid_t H5T_STD_B32LE_g; H5_DLLVAR hid_t H5T_STD_B64BE_g; H5_DLLVAR hid_t H5T_STD_B64LE_g; H5_DLLVAR hid_t H5T_STD_REF_OBJ_g; -H5_DLLVAR hid_t H5T_STD_REF_DSETREG_g; H5_DLLVAR hid_t H5T_STD_REF_REG_g; H5_DLLVAR hid_t H5T_STD_REF_ATTR_g; +H5_DLLVAR hid_t H5T_STD_REF_EXT_OBJ_g; +H5_DLLVAR hid_t H5T_STD_REF_EXT_REG_g; +H5_DLLVAR hid_t H5T_STD_REF_EXT_ATTR_g; /* * Types which are particular to Unix. diff --git a/src/H5Tref.c b/src/H5Tref.c index a55c2e4..a495e225 100644 --- a/src/H5Tref.c +++ b/src/H5Tref.c @@ -28,6 +28,7 @@ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ +#include "H5Rprivate.h" /* References */ #include "H5Tpkg.h" /* Datatypes */ /* Local functions */ @@ -35,11 +36,19 @@ static herr_t H5T__ref_reclaim_recurse(void *elem, const H5T_t *dt); static size_t H5T__ref_mem_getsize(const void *_ref); static herr_t H5T__ref_mem_read(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, size_t buf_size); -static herr_t H5T__ref_mem_write(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, void *_bg, size_t buf_size); +static herr_t H5T__ref_mem_write(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, void *_bg, size_t buf_size, H5R_type_t ref_type); + +static size_t H5T__obj_ref_mem_getsize(const void *_ref); +static herr_t H5T__obj_ref_mem_read(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, size_t buf_size); +static herr_t H5T__obj_ref_mem_write(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, void *_bg, size_t buf_size, H5R_type_t ref_type); static size_t H5T__ref_disk_getsize(const void *_ref); static herr_t H5T__ref_disk_read(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, size_t buf_size); -static herr_t H5T__ref_disk_write(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, void *_bg, size_t buf_size); +static herr_t H5T__ref_disk_write(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, void *_bg, size_t buf_size, H5R_type_t ref_type); + +static size_t H5T__obj_ref_disk_getsize(const void *_ref); +static herr_t H5T__obj_ref_disk_read(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, size_t buf_size); +static herr_t H5T__obj_ref_disk_write(H5F_t *f, hid_t dxpl_id, void *_ref, void *_buf, void *_bg, size_t buf_size, H5R_type_t ref_type); /* Local variables */ @@ -77,18 +86,20 @@ H5T__ref_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) /* Mark this type as being stored in memory */ dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY; - if((dt->shared->u.atomic.u.r.rtype == H5R_REGION) || - (dt->shared->u.atomic.u.r.rtype == H5R_ATTR)) { - /* size in memory, disk size is different */ - dt->shared->size = sizeof(struct href_var); + /* size in memory, disk size is different */ + dt->shared->size = sizeof(href_t); - /* Set up the function pointers to access the region + if (dt->shared->u.atomic.u.r.rtype == H5R_OBJECT) { + /* Set up the function pointers to access the object * reference in memory */ + dt->shared->u.atomic.u.r.getsize = H5T__obj_ref_mem_getsize; + dt->shared->u.atomic.u.r.read = H5T__obj_ref_mem_read; + dt->shared->u.atomic.u.r.write = H5T__obj_ref_mem_write; + } else { + /* Set up the function pointers to access the reference in memory */ dt->shared->u.atomic.u.r.getsize = H5T__ref_mem_getsize; dt->shared->u.atomic.u.r.read = H5T__ref_mem_read; dt->shared->u.atomic.u.r.write = H5T__ref_mem_write; - } else { - HDassert(0 && "Invalid reference type"); } /* Reset file ID (since this reference is in memory) */ @@ -101,21 +112,34 @@ H5T__ref_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc) /* Mark this type as being stored on disk */ dt->shared->u.atomic.u.r.loc = H5T_LOC_DISK; - /* - * Size of element on disk is 4 bytes for the length, plus the size - * of an address in this file, plus 4 bytes for the size of a heap - * ID. Memory size is different - */ - dt->shared->size = (size_t) (2 * H5_SIZEOF_UINT32_T) + H5F_SIZEOF_ADDR(f); - - /* - * Set up the function pointers to access the information on - * disk. Region and attribute references are stored identically - * on disk, so use the same functions - */ - dt->shared->u.atomic.u.r.getsize = H5T__ref_disk_getsize; - dt->shared->u.atomic.u.r.read = H5T__ref_disk_read; - dt->shared->u.atomic.u.r.write = H5T__ref_disk_write; + if (dt->shared->u.atomic.u.r.rtype == H5R_OBJECT) { + /* Size of element on disk */ + dt->shared->size = sizeof(haddr_t); + + /* + * Set up the function pointers to access the information on + * disk + */ + dt->shared->u.atomic.u.r.getsize = H5T__obj_ref_disk_getsize; + dt->shared->u.atomic.u.r.read = H5T__obj_ref_disk_read; + dt->shared->u.atomic.u.r.write = H5T__obj_ref_disk_write; + } else { + /* + * Size of element on disk is 4 bytes for the length, plus the size + * of an address in this file, plus 4 bytes for the size of a heap + * ID. Memory size is different + */ + dt->shared->size = (size_t) (2 * H5_SIZEOF_UINT32_T) + H5F_SIZEOF_ADDR(f); + + /* + * Set up the function pointers to access the information on + * disk. Region and attribute references are stored identically + * on disk, so use the same functions + */ + dt->shared->u.atomic.u.r.getsize = H5T__ref_disk_getsize; + dt->shared->u.atomic.u.r.read = H5T__ref_disk_read; + dt->shared->u.atomic.u.r.write = H5T__ref_disk_write; + } /* Set file ID (since this reference is on disk) */ dt->shared->u.atomic.u.r.f = f; @@ -148,9 +172,9 @@ static size_t H5T__ref_mem_getsize(const void *_ref) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const struct href_var *ref = (const struct href_var *)_ref; + const struct href_t *ref = (const struct href_t *)_ref; #else - struct href_var ref; + struct href_t ref; #endif FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -159,10 +183,10 @@ H5T__ref_mem_getsize(const void *_ref) #ifdef H5_NO_ALIGNMENT_RESTRICTIONS HDassert(ref); - FUNC_LEAVE_NOAPI(ref->buf_size) + FUNC_LEAVE_NOAPI(ref->obj_enc.buf_size) #else HDassert(_ref); - HDmemcpy(&ref, _ref, sizeof(struct href_var)); + HDmemcpy(&ref, _ref, sizeof(struct href_t)); FUNC_LEAVE_NOAPI(ref.buf_size) #endif @@ -182,9 +206,9 @@ H5T__ref_mem_read(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, void *_ref, void *buf, size_t buf_size) { #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - const struct href_var *ref = (const struct href_var *)_ref; + const struct href_t *ref = (const struct href_t *)_ref; #else - struct href_var ref; + struct href_t ref; #endif FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -192,15 +216,15 @@ H5T__ref_mem_read(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, /* check parameters, copy data */ HDassert(buf); #ifdef H5_NO_ALIGNMENT_RESTRICTIONS - HDassert(ref && ref->buf); + HDassert(ref && ref->obj_enc.buf); - HDmemcpy(buf, ref->buf, buf_size); + HDmemcpy(buf, ref->obj_enc.buf, buf_size); #else HDassert(_ref); - HDmemcpy(&ref, _ref, sizeof(struct href_var)); - HDassert(ref.buf); + HDmemcpy(&ref, _ref, sizeof(struct href_t)); + HDassert(ref.obj_enc.buf); - HDmemcpy(buf, ref.buf, buf_size); + HDmemcpy(buf, ref.obj_enc.buf, buf_size); #endif FUNC_LEAVE_NOAPI(SUCCEED) @@ -217,9 +241,9 @@ H5T__ref_mem_read(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, */ static herr_t H5T__ref_mem_write(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, - void *_ref, void *buf, void H5_ATTR_UNUSED *_bg, size_t buf_size) + void *_ref, void *buf, void H5_ATTR_UNUSED *_bg, size_t buf_size, H5R_type_t ref_type) { - struct href_var ref; + struct href_t ref; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -229,26 +253,118 @@ H5T__ref_mem_write(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, HDassert(buf); if (buf_size != 0) { - if (NULL == (ref.buf = H5MM_malloc(buf_size))) + if (NULL == (ref.obj_enc.buf = H5MM_malloc(buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for reference data") /* Copy the data into the newly allocated buffer */ - HDmemcpy(ref.buf, buf, buf_size); + HDmemcpy(ref.obj_enc.buf, buf, buf_size); } /* end if */ else - ref.buf = NULL; + ref.obj_enc.buf = NULL; /* Set the size */ - ref.buf_size = buf_size; + ref.obj_enc.buf_size = buf_size; + + /* Set the type */ + ref.ref_type = ref_type; /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ - HDmemcpy(_ref, &ref, sizeof(struct href_var)); + HDmemcpy(_ref, &ref, sizeof(struct href_t)); done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__ref_mem_write() */ /*------------------------------------------------------------------------- + * Function: H5T__obj_ref_mem_getsize + * + * Purpose: Retrieves the size of a memory based object reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static size_t +H5T__obj_ref_mem_getsize(const void H5_ATTR_UNUSED *_ref) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + FUNC_LEAVE_NOAPI(sizeof(haddr_t)) +} /* end H5T__obj_ref_mem_getsize() */ + +/*------------------------------------------------------------------------- + * Function: H5T__obj_ref_mem_read + * + * Purpose: "Reads" the memory based object reference into a buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__obj_ref_mem_read(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, + void *_ref, void *buf, size_t buf_size) +{ +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + const struct href_t *ref = (const struct href_t *)_ref; +#else + struct href_t ref; +#endif + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* check parameters, copy data */ + HDassert(buf); +#ifdef H5_NO_ALIGNMENT_RESTRICTIONS + HDassert(ref); + + HDmemcpy(buf, &ref->obj_addr, sizeof(haddr_t)); +#else + HDassert(_ref); + HDmemcpy(&ref, _ref, sizeof(struct href_t)); + + HDmemcpy(buf, &ref.obj_addr, sizeof(haddr_t)); +#endif + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T__obj_ref_mem_read() */ + +/*------------------------------------------------------------------------- + * Function: H5T__obj_ref_mem_write + * + * Purpose: "Writes" the memory object reference from a buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__obj_ref_mem_write(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, + void *_ref, void *buf, void H5_ATTR_UNUSED *_bg, size_t buf_size, H5R_type_t ref_type) +{ + struct href_t ref; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* check parameters */ + HDassert(_ref); + HDassert(buf); + HDassert(buf_size == sizeof(haddr_t)); + + /* Copy the data into the newly allocated buffer */ + HDmemcpy(&ref.obj_addr, buf, buf_size); + + /* Set the type */ + ref.ref_type = ref_type; + + /* Set pointer in user's buffer with memcpy, to avoid alignment issues */ + HDmemcpy(_ref, &ref, sizeof(struct href_t)); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__obj_ref_mem_write() */ + +/*------------------------------------------------------------------------- * Function: H5T__ref_disk_getsize * * Purpose: Retrieves the length of a disk based reference. @@ -326,7 +442,7 @@ done: */ static herr_t H5T__ref_disk_write(H5F_t *f, hid_t dxpl_id, void *_ref, void *buf, void *_bg, - size_t buf_size) + size_t buf_size, H5R_type_t H5_ATTR_UNUSED ref_type) { uint8_t *ref = (uint8_t *)_ref; /* Pointer to the user's information */ const uint8_t *bg = (const uint8_t *)_bg; /* Pointer to the old data */ @@ -340,9 +456,8 @@ H5T__ref_disk_write(H5F_t *f, hid_t dxpl_id, void *_ref, void *buf, void *_bg, HDassert(buf_size == 0 || buf); HDassert(f); - /* TODO not sure if we need that but oh well... */ /* Free heap object for old data. */ - if(bg != NULL) { + if(bg != NULL) { /* TODO Should get rid of bg stuff */ H5HG_t bg_hobjid; /* "Background" reference's ID info */ /* Skip the length of the reference and heap object ID from background data. */ @@ -376,6 +491,75 @@ done: } /* end H5T__ref_disk_write() */ /*------------------------------------------------------------------------- + * Function: H5T__obj_ref_disk_getsize + * + * Purpose: Retrieves the length of a disk based object reference. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static size_t +H5T__obj_ref_disk_getsize(const void H5_ATTR_UNUSED *_ref) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + FUNC_LEAVE_NOAPI(sizeof(haddr_t)) +} /* end H5T__obj_ref_disk_getsize() */ + +/*------------------------------------------------------------------------- + * Function: H5T__obj_ref_disk_read + * + * Purpose: Reads the disk based object reference into a buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__obj_ref_disk_read(H5F_t H5_ATTR_UNUSED *f, hid_t dxpl_id, void *_ref, void *buf, + size_t H5_ATTR_UNUSED buf_size) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* check parameters */ + HDassert(_ref); + HDassert(buf); + + HDmemcpy(buf, _ref, sizeof(haddr_t)); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__obj_ref_disk_read() */ + +/*------------------------------------------------------------------------- + * Function: H5T__obj_ref_disk_write + * + * Purpose: Writes the disk based object reference from a buffer + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5T__obj_ref_disk_write(H5F_t H5_ATTR_UNUSED *f, hid_t dxpl_id, void *_ref, void *buf, void *_bg, + size_t buf_size, H5R_type_t H5_ATTR_UNUSED ref_type) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* check parameters */ + HDassert(_ref); + HDassert(buf_size == 0 || buf); + + HDmemcpy(_ref, buf, sizeof(haddr_t)); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T__obj_ref_disk_write() */ + +/*------------------------------------------------------------------------- * Function: H5T__ref_reclaim_recurse * * Purpose: Internal recursive routine to free reference datatypes @@ -397,16 +581,13 @@ H5T__ref_reclaim_recurse(void *elem, const H5T_t *dt) /* Check the datatype of this element */ switch(dt->shared->type) { case H5T_REFERENCE: - if((dt->shared->u.atomic.u.r.rtype == H5R_REGION) || - (dt->shared->u.atomic.u.r.rtype == H5R_ATTR)) { - struct href_var *ref = (struct href_var *)elem; - - if(ref->buf_size != 0) { - ref->buf = H5MM_xfree(ref->buf); - } /* end if */ - } else { - HDassert(0 && "Invalid reference type"); - } /* end else */ + { + struct href_t *ref = (struct href_t *)elem; + + if((ref->ref_type != H5R_OBJECT) && (ref->obj_enc.buf_size != 0)) { + ref->obj_enc.buf = H5MM_xfree(ref->obj_enc.buf); + } /* end if */ + } break; /* Don't do anything for other types */ diff --git a/src/H5detect.c b/src/H5detect.c index ad0205b..bfb952b 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -56,7 +56,7 @@ static const char *FileHeader = "\n\ #undef NDEBUG #include "H5private.h" #include "H5Tpublic.h" -#include "H5Rpublic.h" +#include "H5Rprivate.h" #define MAXDETECT 64 @@ -1653,14 +1653,10 @@ detect_C99_floats(void) static void detect_alignments(void) { - /* Detect structure alignment for pointers, hvl_t, hobj_ref_t, - * hdset_reg_ref_t, hattr_ref_t, hreg_ref_t */ + /* Detect structure alignment for pointers, hvl_t, href_t */ DETECT_M(void *, POINTER, m_g[na_g]); na_g++; DETECT_M(hvl_t, HVL, m_g[na_g]); na_g++; - DETECT_M(hobj_ref_t, HOBJREF, m_g[na_g]); na_g++; - DETECT_M(hdset_reg_ref_t, HDSETREGREF, m_g[na_g]); na_g++; - DETECT_M(hreg_ref_t, HREGREF, m_g[na_g]); na_g++; - DETECT_M(hattr_ref_t, HATTRREF, m_g[na_g]); na_g++; + DETECT_M(href_t, HREF, m_g[na_g]); na_g++; } diff --git a/src/H5trace.c b/src/H5trace.c index ec4dcbf..9fd1007 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -36,6 +36,7 @@ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5FDprivate.h" /* File drivers */ +#include "H5Rprivate.h" /* References */ #include "H5Ipkg.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Qprivate.h" /* Queries */ @@ -1762,9 +1763,8 @@ H5_trace(const double *returning, const char *func, const char *type, ...) fprintf(out, "NULL"); } /* end if */ else { - hobj_ref_t ref = va_arg(ap, hobj_ref_t); /*lint !e732 Loss of sign not really occuring */ - - HDfprintf(out, "Reference Object=%a", ref); + fprintf(out, "OPAQUE TYPE"); + goto error; } /* end else */ break; @@ -1884,8 +1884,8 @@ H5_trace(const double *returning, const char *func, const char *type, ...) fprintf(out, "H5R_OBJECT"); break; - case H5R_DATASET_REGION: - fprintf(out, "H5R_DATASET_REGION"); + case H5R_REGION: + fprintf(out, "H5R_REGION"); break; case H5R_ATTR: |