summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/trace1
-rw-r--r--src/H5HGprivate.h4
-rw-r--r--src/H5Tvlen.c69
-rw-r--r--src/H5VLcallback.c288
-rw-r--r--src/H5VLconnector.h10
-rw-r--r--src/H5VLconnector_passthru.h5
-rw-r--r--src/H5VLnative.c2
-rw-r--r--src/H5VLnative.h4
-rw-r--r--src/H5VLnative_blob.c71
-rw-r--r--src/H5VLnative_private.h7
-rw-r--r--src/H5VLpassthru.c92
-rw-r--r--src/H5VLpassthru.h3
-rw-r--r--src/H5VLprivate.h9
-rw-r--r--src/H5trace.c29
14 files changed, 490 insertions, 104 deletions
diff --git a/bin/trace b/bin/trace
index 54b6f8f..fe0443d 100755
--- a/bin/trace
+++ b/bin/trace
@@ -99,6 +99,7 @@ $Source = "";
"unsigned long long" => "UL",
"H5VL_attr_get_t" => "Va",
"H5VL_attr_specific_t" => "Vb",
+ "H5VL_blob_specific_t" => "VB",
"H5VL_class_value_t" => "VC",
"H5VL_dataset_get_t" => "Vc",
"H5VL_dataset_specific_t" => "Vd",
diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h
index 1c609e2..4841847 100644
--- a/src/H5HGprivate.h
+++ b/src/H5HGprivate.h
@@ -49,6 +49,10 @@ typedef struct H5HG_heap_t H5HG_heap_t;
#define H5HG_FREE_SIZE(H) (H5HG_get_free_size(H))
#endif /* H5HG_MODULE */
+/* Size of encoded global heap ID */
+/* (size of file address + 32-bit integer) */
+#define H5HG_HEAP_ID_SIZE(F) ((size_t)H5F_SIZEOF_ADDR(F) + H5_SIZEOF_UINT32_T)
+
/* Main global heap routines */
H5_DLL herr_t H5HG_insert(H5F_t *f, size_t size, void *obj, H5HG_t *hobj/*out*/);
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index e14bd27..939a26d 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -21,7 +21,7 @@
/****************/
#include "H5Tmodule.h" /* This source code file is part of the H5T module */
-
+#define H5F_FRIEND /*suppress error about including H5Fpkg */
/***********/
/* Headers */
@@ -30,6 +30,7 @@
#include "H5CXprivate.h" /* API Contexts */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fprivate.h" /* File access */
+#include "H5Fpkg.h" /* File */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Tpkg.h" /* Datatypes */
@@ -849,7 +850,9 @@ done:
static herr_t
H5T__vlen_disk_isnull(const H5F_t *f, void *_vl, hbool_t *isnull)
{
- const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */
+ H5VL_object_t *vol_obj = NULL;/* Object info */
+ hid_t file_id = H5I_INVALID_HID;
+ uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -862,11 +865,19 @@ H5T__vlen_disk_isnull(const H5F_t *f, void *_vl, hbool_t *isnull)
/* Skip the sequence's length */
vl += 4;
+ /* TODO temporary hack to retrieve file object */
+ if((file_id = H5F__get_file_id((H5F_t *)f, FALSE)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
+ if(NULL == (vol_obj = H5VL_vol_object(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+
/* Check if blob ID is "nil" */
- if(H5VL_blob_specific(H5F_VOL_CLS(f), vl, H5VL_BLOB_ISNULL, f, isnull) < 0)
+ if(H5VL_blob_specific(vol_obj, vl, H5VL_BLOB_ISNULL, isnull) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'")
done:
+ if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0))
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__vlen_disk_isnull() */
@@ -886,6 +897,8 @@ done:
static herr_t
H5T__vlen_disk_setnull(H5F_t *f, void *_vl, void *bg)
{
+ H5VL_object_t *vol_obj = NULL;/* Object info */
+ hid_t file_id = H5I_INVALID_HID;
uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */
herr_t ret_value = SUCCEED; /* Return value */
@@ -904,11 +917,19 @@ H5T__vlen_disk_setnull(H5F_t *f, void *_vl, void *bg)
/* Set the length of the sequence */
UINT32ENCODE(vl, 0);
+ /* TODO temporary hack to retrieve file object */
+ if((file_id = H5F__get_file_id(f, FALSE)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
+ if(NULL == (vol_obj = H5VL_vol_object(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+
/* Set blob ID to "nil" */
- if(H5VL_blob_specific(H5F_VOL_CLS(f), vl, H5VL_BLOB_SETNULL, f) < 0)
+ if(H5VL_blob_specific(vol_obj, vl, H5VL_BLOB_SETNULL) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'")
done:
+ if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0))
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__vlen_disk_setnull() */
@@ -928,6 +949,8 @@ done:
static herr_t
H5T__vlen_disk_read(H5F_t *f, void *_vl, void *buf, size_t H5_ATTR_UNUSED len)
{
+ H5VL_object_t *vol_obj = NULL;/* Object info */
+ hid_t file_id = H5I_INVALID_HID;
const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */
herr_t ret_value = SUCCEED; /* Return value */
@@ -941,11 +964,19 @@ H5T__vlen_disk_read(H5F_t *f, void *_vl, void *buf, size_t H5_ATTR_UNUSED len)
/* Skip the length of the sequence */
vl += 4;
+ /* TODO temporary hack to retrieve file object */
+ if((file_id = H5F__get_file_id(f, FALSE)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
+ if(NULL == (vol_obj = H5VL_vol_object(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+
/* Retrieve blob */
- if(H5VL_blob_get(H5F_VOL_CLS(f), vl, f, buf) < 0)
+ if(H5VL_blob_get(vol_obj, vl, buf, NULL, NULL) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get blob")
done:
+ if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0))
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__vlen_disk_read() */
@@ -966,6 +997,8 @@ static herr_t
H5T__vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_alloc_info,
void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size)
{
+ H5VL_object_t *vol_obj = NULL; /* Object info */
+ hid_t file_id = H5I_INVALID_HID;
uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */
const uint8_t *bg = (const uint8_t *)_bg; /* Pointer to the old data hvl_t */
herr_t ret_value = SUCCEED; /* Return value */
@@ -985,11 +1018,19 @@ H5T__vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_al
/* Set the length of the sequence */
UINT32ENCODE(vl, seq_len);
+ /* TODO temporary hack to retrieve file object */
+ if((file_id = H5F__get_file_id(f, FALSE)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
+ if(NULL == (vol_obj = H5VL_vol_object(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+
/* Store blob */
- if(H5VL_blob_put(H5F_VOL_CLS(f), buf, (seq_len * base_size), f, vl) < 0)
+ if(H5VL_blob_put(vol_obj, buf, (seq_len * base_size), vl, NULL) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to put blob")
done:
+ if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0))
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__vlen_disk_write() */
@@ -1010,6 +1051,7 @@ static herr_t
H5T__vlen_disk_delete(H5F_t *f, const void *_vl)
{
const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */
+ hid_t file_id = H5I_INVALID_HID;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -1025,12 +1067,23 @@ H5T__vlen_disk_delete(H5F_t *f, const void *_vl)
UINT32DECODE(vl, seq_len);
/* Delete object, if length > 0 */
- if(seq_len > 0)
- if(H5VL_blob_specific(H5F_VOL_CLS(f), (void *)vl, H5VL_BLOB_DELETE, f) < 0) /* Casting away 'const' OK -QAK */
+ if(seq_len > 0) {
+ H5VL_object_t *vol_obj = NULL; /* Object info */
+
+ /* TODO temporary hack to retrieve file object */
+ if((file_id = H5F__get_file_id(f, FALSE)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
+ if(NULL == (vol_obj = H5VL_vol_object(file_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier")
+
+ if(H5VL_blob_specific(vol_obj, (void *)vl, H5VL_BLOB_DELETE) < 0) /* Casting away 'const' OK -QAK */
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob")
+ }
} /* end if */
done:
+ if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0))
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T__vlen_disk_delete() */
diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c
index 43739a6..5400356 100644
--- a/src/H5VLcallback.c
+++ b/src/H5VLcallback.c
@@ -177,7 +177,12 @@ static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls,
static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls,
va_list arguments);
static herr_t H5VL__request_free(void *req, const H5VL_class_t *cls);
-
+static herr_t H5VL__blob_put(void *obj, const H5VL_class_t *cls,
+ const void *buf, size_t size, void *blob_id, void *ctx);
+static herr_t H5VL__blob_get(void *obj, const H5VL_class_t *cls,
+ const void *blob_id, void *buf, size_t *size, void *ctx);
+static herr_t H5VL__blob_specific(void *obj, const H5VL_class_t *cls,
+ void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments);
/*********************/
/* Package Variables */
@@ -6564,81 +6569,230 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5VL_blob_put
+ * Function: H5VL__blob_put
*
* Purpose: Put a blob through the VOL
*
* Return: SUCCEED / FAIL
*
- * Programmer: Quincey Koziol
- * Wednesday, August 21, 2019
- *
*-------------------------------------------------------------------------
*/
-herr_t
-H5VL_blob_put(const H5VL_class_t *cls, void *blob, size_t size, void *ctx, void *id)
+static herr_t
+H5VL__blob_put(void *obj, const H5VL_class_t *cls, const void *buf, size_t size,
+ void *blob_id, void *ctx)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Sanity check */
+ HDassert(obj);
HDassert(cls);
- HDassert(size == 0 || blob);
- HDassert(id);
+ HDassert(size == 0 || buf);
+ HDassert(blob_id);
/* Check if the corresponding VOL callback exists */
if(NULL == cls->blob_cls.put)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob put' method")
/* Call the corresponding VOL callback */
- if((cls->blob_cls.put)(blob, size, ctx, id) < 0)
+ if((cls->blob_cls.put)(obj, buf, size, blob_id, ctx) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put callback failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5VL_blob_put() */
+} /* end H5VL__blob_put() */
/*-------------------------------------------------------------------------
- * Function: H5VL_blob_get
+ * Function: H5VL_blob_put
*
- * Purpose: Get a blob through the VOL
+ * Purpose: Put a blob through the VOL
*
* Return: SUCCEED / FAIL
*
* Programmer: Quincey Koziol
- * Friday, August 16, 2019
+ * Wednesday, August 21, 2019
*
*-------------------------------------------------------------------------
*/
herr_t
-H5VL_blob_get(const H5VL_class_t *cls, const void *id, void *ctx, void *buf)
+H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size,
+ void *blob_id, void *ctx)
{
+ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/* Sanity check */
+ HDassert(vol_obj);
+ HDassert(size == 0 || buf);
+ HDassert(blob_id);
+
+ /* Set wrapper info in API context */
+ if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
+ vol_wrapper_set = TRUE;
+
+ /* Call the corresponding VOL callback */
+ if(H5VL__blob_put(vol_obj->data, vol_obj->connector->cls, buf, size, blob_id, ctx) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed")
+
+done:
+ /* Reset object wrapping info in API context */
+ if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
+ HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_blob_put() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VLblob_put
+ *
+ * Purpose: Put a blob through the VOL
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_t size,
+ void *blob_id, void *ctx)
+{
+ H5VL_class_t *cls; /* VOL connector's class struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API_NOINIT
+ H5TRACE6("e", "*xi*xz*x*x", obj, connector_id, buf, size, blob_id, ctx);
+
+ /* Get class pointer */
+ if(NULL == obj)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object")
+ if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID")
+
+ /* Call the corresponding VOL callback */
+ if(H5VL__blob_put(obj, cls, buf, size, blob_id, ctx) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed")
+
+done:
+ FUNC_LEAVE_API_NOINIT(ret_value)
+} /* end H5VLblob_put() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__blob_get
+ *
+ * Purpose: Get a blob through the VOL
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL__blob_get(void *obj, const H5VL_class_t *cls, const void *blob_id,
+ void *buf, size_t *size, void *ctx)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(obj);
HDassert(cls);
- HDassert(id);
- HDassert(buf);
+ HDassert(blob_id);
+ HDassert(size || buf);
/* Check if the corresponding VOL callback exists */
if(NULL == cls->blob_cls.get)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob get' method")
/* Call the corresponding VOL callback */
- if((cls->blob_cls.get)(id, ctx, buf) < 0)
+ if((cls->blob_cls.get)(obj, blob_id, buf, size, ctx) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get callback failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__blob_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_blob_get
+ *
+ * Purpose: Get a blob through the VOL
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf,
+ size_t *size, void *ctx)
+{
+ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(vol_obj);
+ HDassert(blob_id);
+ HDassert(size || buf);
+
+ /* Set wrapper info in API context */
+ if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
+ vol_wrapper_set = TRUE;
+
+ /* Call the corresponding VOL callback */
+ if(H5VL__blob_get(vol_obj->data, vol_obj->connector->cls, blob_id, buf, size, ctx) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed")
+
+done:
+ /* Reset object wrapping info in API context */
+ if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
+ HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_blob_get() */
/*-------------------------------------------------------------------------
- * Function: H5VL_blob_specific
+ * Function: H5VLblob_get
+ *
+ * Purpose: Get a blob through the VOL
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf,
+ size_t *size, void *ctx)
+{
+ H5VL_class_t *cls; /* VOL connector's class struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API_NOINIT
+ H5TRACE6("e", "*xi*x*x*z*x", obj, connector_id, blob_id, buf, size, ctx);
+
+ /* Get class pointer */
+ if(NULL == obj)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object")
+ if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID")
+
+ /* Call the corresponding VOL callback */
+ if(H5VL__blob_get(obj, cls, blob_id, buf, size, ctx) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed")
+
+done:
+ FUNC_LEAVE_API_NOINIT(ret_value)
+} /* end H5VLblob_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__blob_specific
*
* Purpose: Specific operation on blobs through the VOL
*
@@ -6649,28 +6803,66 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5VL_blob_specific(const H5VL_class_t *cls, void *id,
- H5VL_blob_specific_t specific_type, ...)
+static herr_t
+H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id,
+ H5VL_blob_specific_t specific_type, va_list arguments)
{
- va_list arguments; /* Argument list passed from the API call */
- hbool_t arg_started = FALSE; /* Whether the va_list has been started */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Sanity check */
+ HDassert(obj);
HDassert(cls);
- HDassert(id);
+ HDassert(blob_id);
/* Check if the corresponding VOL callback exists */
if(NULL == cls->blob_cls.specific)
HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob specific' method")
/* Call the corresponding VOL callback */
+ if((cls->blob_cls.specific)(obj, blob_id, specific_type, arguments) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL__blob_specific() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_blob_specific
+ *
+ * Purpose: Specific operation on blobs through the VOL
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id,
+ H5VL_blob_specific_t specific_type, ...)
+{
+ va_list arguments; /* Argument list passed from the API call */
+ hbool_t arg_started = FALSE; /* Whether the va_list has been started */
+ hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(vol_obj);
+ HDassert(blob_id);
+
+ /* Set wrapper info in API context */
+ if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info")
+ vol_wrapper_set = TRUE;
+
+ /* Call the corresponding internal VOL routine */
HDva_start(arguments, specific_type);
arg_started = TRUE;
- if((cls->blob_cls.specific)(id, specific_type, arguments) < 0)
+ if((ret_value = H5VL__blob_specific(vol_obj->data, vol_obj->connector->cls, blob_id, specific_type, arguments)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback")
done:
@@ -6678,8 +6870,46 @@ done:
if(arg_started)
HDva_end(arguments);
+ /* Reset object wrapping info in API context */
+ if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0)
+ HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info")
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5VL_blob_get() */
+} /* end H5VL_blob_specific() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VLblob_specific
+ *
+ * Purpose: Specific operation on blobs through the VOL
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id,
+ H5VL_blob_specific_t specific_type, va_list arguments)
+{
+ H5VL_class_t *cls; /* VOL connector's class struct */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API_NOINIT
+ H5TRACE5("e", "*xi*xVBx", obj, connector_id, blob_id, specific_type, arguments);
+
+ /* Get class pointer */
+ if(NULL == obj)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object")
+ if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID")
+
+ /* Call the corresponding VOL callback */
+ if(H5VL__blob_specific(obj, cls, blob_id, specific_type, arguments) < 0)
+ HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "blob specific operation failed")
+
+done:
+ FUNC_LEAVE_API_NOINIT(ret_value)
+} /* end H5VLblob_specific() */
/*-------------------------------------------------------------------------
diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h
index c554dab..1221d88 100644
--- a/src/H5VLconnector.h
+++ b/src/H5VLconnector.h
@@ -37,6 +37,8 @@
#define H5VL_CAP_FLAG_NONE 0 /* No special connector capabilities */
#define H5VL_CAP_FLAG_THREADSAFE 0x01 /* Connector is threadsafe */
+/* The maximum size allowed for blobs */
+#define H5VL_MAX_BLOB_ID_SIZE (16) /* Allow for 128-bits blob IDs */
/*******************/
/* Public Typedefs */
@@ -365,10 +367,10 @@ typedef struct H5VL_request_class_t {
/* 'blob' routines */
typedef struct H5VL_blob_class_t {
- herr_t (*put)(void *blob, size_t size, void *ctx, void *id);
- herr_t (*get)(const void *id, void *ctx, void *blob);
- herr_t (*specific)(void *id, H5VL_blob_specific_t specific_type, va_list arguments);
- herr_t (*optional)(void *id, va_list arguments);
+ herr_t (*put)(void *obj, const void *buf, size_t size, void *blob_id, void *ctx);
+ herr_t (*get)(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx);
+ herr_t (*specific)(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments);
+ herr_t (*optional)(void *obj, void *blob_id, va_list arguments);
} H5VL_blob_class_t;
/*
diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h
index 65c9117..d0d73d2 100644
--- a/src/H5VLconnector_passthru.h
+++ b/src/H5VLconnector_passthru.h
@@ -158,6 +158,11 @@ H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_s
H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, va_list arguments);
H5_DLL herr_t H5VLrequest_free(void *req, hid_t connector_id);
+/* Public wrappers for blob callbacks */
+H5_DLL herr_t H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_t size, void *blob_id, void *ctx);
+H5_DLL herr_t H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf, size_t *size, void *ctx);
+H5_DLL herr_t H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments);
+
/* Public wrappers for generic 'optional' callback */
H5_DLL herr_t H5VLoptional(void *obj, hid_t connector_id, hid_t dxpl_id,
void **req, va_list arguments);
diff --git a/src/H5VLnative.c b/src/H5VLnative.c
index c705aad..78eaee4 100644
--- a/src/H5VLnative.c
+++ b/src/H5VLnative.c
@@ -124,7 +124,7 @@ static H5VL_class_t H5VL_native_cls_g = {
H5VL__native_blob_put, /* put */
H5VL__native_blob_get, /* get */
H5VL__native_blob_specific, /* specific */
- H5VL__native_blob_optional /* optional */
+ NULL /* optional */
},
NULL /* optional */
};
diff --git a/src/H5VLnative.h b/src/H5VLnative.h
index 96668ac..5b51e66 100644
--- a/src/H5VLnative.h
+++ b/src/H5VLnative.h
@@ -17,8 +17,8 @@
#ifndef _H5VLnative_H
#define _H5VLnative_H
-/* Private headers needed by this file */
-#include "H5VLprivate.h" /* Virtual Object Layer */
+/* Public headers needed by this file */
+#include "H5VLpublic.h" /* Virtual Object Layer */
/* Identifier for the native VOL connector */
#define H5VL_NATIVE (H5VL_native_register())
diff --git a/src/H5VLnative_blob.c b/src/H5VLnative_blob.c
index 6f2fbe6..b16b407 100644
--- a/src/H5VLnative_blob.c
+++ b/src/H5VLnative_blob.c
@@ -68,22 +68,23 @@
*-------------------------------------------------------------------------
*/
herr_t
-H5VL__native_blob_put(void *blob, size_t size, void *_ctx, void *_id)
+H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id,
+ void H5_ATTR_UNUSED *ctx)
{
- uint8_t *id = (uint8_t *)_id; /* Pointer to blob ID */
- H5F_t *f = (H5F_t *)_ctx; /* Retrieve file pointer from context */
+ H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */
+ uint8_t *id = (uint8_t *)blob_id; /* Pointer to blob ID */
H5HG_t hobjid; /* New VL sequence's heap ID */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Check parameters */
- HDassert(id);
- HDassert(size == 0 || blob);
HDassert(f);
+ HDassert(size == 0 || buf);
+ HDassert(id);
/* Write the VL information to disk (allocates space also) */
- if(H5HG_insert(f, size, blob, &hobjid) < 0)
+ if(H5HG_insert(f, size, (void *)buf, &hobjid) < 0)
HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "unable to write blob information")
/* Encode the heap information */
@@ -108,18 +109,19 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5VL__native_blob_get(const void *_id, void *_ctx, void *buf)
+H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t *size,
+ void H5_ATTR_UNUSED *ctx)
{
- const uint8_t *id = (const uint8_t *)_id; /* Pointer to the disk blob ID */
- H5F_t *f = (H5F_t *)_ctx; /* Retrieve file pointer from context */
+ H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */
+ const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the disk blob ID */
H5HG_t hobjid; /* Global heap ID for sequence */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Sanity check */
- HDassert(id);
HDassert(f);
+ HDassert(id);
HDassert(buf);
/* Get the heap information */
@@ -129,7 +131,7 @@ H5VL__native_blob_get(const void *_id, void *_ctx, void *buf)
/* Check if this sequence actually has any data */
if(hobjid.addr > 0)
/* Read the VL information from disk */
- if(NULL == H5HG_read(f, &hobjid, buf, NULL))
+ if(NULL == H5HG_read(f, &hobjid, buf, size))
HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "unable to read VL information")
done:
@@ -150,18 +152,22 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type,
- va_list arguments)
+H5VL__native_blob_specific(void *obj, void *blob_id,
+ H5VL_blob_specific_t specific_type, va_list arguments)
{
+ H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
+ /* Sanity check */
+ HDassert(f);
+ HDassert(blob_id);
+
switch(specific_type) {
case H5VL_BLOB_GETSIZE:
{
- const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */
- H5F_t *f = HDva_arg(arguments, H5F_t *);
+ const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */
size_t *size = HDva_arg(arguments, size_t *);
H5HG_t hobjid; /* blob's heap ID */
@@ -182,8 +188,7 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type,
case H5VL_BLOB_ISNULL:
{
- const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */
- H5F_t *f = HDva_arg(arguments, H5F_t *);
+ const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */
hbool_t *isnull = HDva_arg(arguments, hbool_t *);
haddr_t addr; /* Sequence's heap address */
@@ -198,9 +203,7 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type,
case H5VL_BLOB_SETNULL:
{
- uint8_t *id = (uint8_t *)_id; /* Pointer to the blob ID */
- H5F_t *f = HDva_arg(arguments, H5F_t *);
-
+ uint8_t *id = (uint8_t *)blob_id; /* Pointer to the blob ID */
/* Encode the "nil" heap pointer information */
H5F_addr_encode(f, &id, (haddr_t)0);
UINT32ENCODE(id, 0);
@@ -210,8 +213,7 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type,
case H5VL_BLOB_DELETE:
{
- const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */
- H5F_t *f = HDva_arg(arguments, H5F_t *);
+ const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */
H5HG_t hobjid; /* VL sequence's heap ID */
/* Get heap information */
@@ -233,28 +235,3 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type,
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL__native_blob_specific() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5VL__native_blob_optional
- *
- * Purpose: Handles the blob 'optional' callback
- *
- * Return: SUCCEED / FAIL
- *
- * Programmer: Quincey Koziol
- * Friday, August 15, 2019
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5VL__native_blob_optional(void *id, va_list arguments)
-{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_PACKAGE
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5VL__native_blob_optional() */
-
diff --git a/src/H5VLnative_private.h b/src/H5VLnative_private.h
index df3865b..5ed0b1f 100644
--- a/src/H5VLnative_private.h
+++ b/src/H5VLnative_private.h
@@ -102,10 +102,9 @@ H5_DLL herr_t H5VL__native_datatype_specific(void *dt, H5VL_datatype_specific_t
H5_DLL herr_t H5VL__native_datatype_close(void *dt, hid_t dxpl_id, void **req);
/* Blob callbacks */
-H5_DLL herr_t H5VL__native_blob_put(void *blob, size_t size, void *ctx, void *id);
-H5_DLL herr_t H5VL__native_blob_get(const void *id, void *ctx, void *buf);
-H5_DLL herr_t H5VL__native_blob_specific(void *id, H5VL_blob_specific_t specific_type, va_list arguments);
-H5_DLL herr_t H5VL__native_blob_optional(void *id, va_list arguments);
+H5_DLL herr_t H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx);
+H5_DLL herr_t H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx);
+H5_DLL herr_t H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments);
#ifdef __cplusplus
}
diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c
index 48ef510..85c2211 100644
--- a/src/H5VLpassthru.c
+++ b/src/H5VLpassthru.c
@@ -178,6 +178,12 @@ static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specifi
static herr_t H5VL_pass_through_request_optional(void *req, va_list arguments);
static herr_t H5VL_pass_through_request_free(void *req);
+/* Blob callbacks */
+static herr_t H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx);
+static herr_t H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx);
+static herr_t H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments);
+
+
/*******************/
/* Local variables */
/*******************/
@@ -273,9 +279,9 @@ static const H5VL_class_t H5VL_pass_through_g = {
H5VL_pass_through_request_free /* free */
},
{ /* blob_cls */
- NULL, /* put */
- NULL, /* get */
- NULL, /* specific */
+ H5VL_pass_through_blob_put, /* put */
+ H5VL_pass_through_blob_get, /* get */
+ H5VL_pass_through_blob_specific, /* specific */
NULL /* optional */
},
NULL /* optional */
@@ -2840,3 +2846,83 @@ H5VL_pass_through_request_free(void *obj)
return ret_value;
} /* end H5VL_pass_through_request_free() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_blob_put
+ *
+ * Purpose: Handles the blob 'put' callback
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size,
+ void *blob_id, void *ctx)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_PASSTHRU_LOGGING
+ printf("------- PASS THROUGH VOL BLOB Put\n");
+#endif
+
+ ret_value = H5VLblob_put(o->under_object, o->under_vol_id, buf, size,
+ blob_id, ctx);
+
+ return ret_value;
+} /* end H5VL_pass_through_blob_put() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_blob_get
+ *
+ * Purpose: Handles the blob 'get' callback
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf,
+ size_t *size, void *ctx)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_PASSTHRU_LOGGING
+ printf("------- PASS THROUGH VOL BLOB Get\n");
+#endif
+
+ ret_value = H5VLblob_get(o->under_object, o->under_vol_id, blob_id, buf,
+ size, ctx);
+
+ return ret_value;
+} /* end H5VL_pass_through_blob_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_blob_specific
+ *
+ * Purpose: Handles the blob 'specific' callback
+ *
+ * Return: SUCCEED / FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_pass_through_blob_specific(void *obj, void *blob_id,
+ H5VL_blob_specific_t specific_type, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_PASSTHRU_LOGGING
+ printf("------- PASS THROUGH VOL BLOB Specific\n");
+#endif
+
+ ret_value = H5VLblob_specific(o->under_object, o->under_vol_id, blob_id,
+ specific_type, arguments);
+
+ return ret_value;
+} /* end H5VL_pass_through_blob_specific() */
diff --git a/src/H5VLpassthru.h b/src/H5VLpassthru.h
index e640636..d145bcd 100644
--- a/src/H5VLpassthru.h
+++ b/src/H5VLpassthru.h
@@ -17,6 +17,9 @@
#ifndef _H5VLpassthru_H
#define _H5VLpassthru_H
+/* Public headers needed by this file */
+#include "H5VLpublic.h" /* Virtual Object Layer */
+
/* Identifier for the pass-through VOL connector */
#define H5VL_PASSTHRU (H5VL_pass_through_register())
diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h
index 4aeabfa..2889524 100644
--- a/src/H5VLprivate.h
+++ b/src/H5VLprivate.h
@@ -194,12 +194,9 @@ H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, ...);
H5_DLL herr_t H5VL_request_free(const H5VL_object_t *vol_obj);
/* Blob functions */
-H5_DLL herr_t H5VL_blob_put(const H5VL_class_t *cls, void *blob, size_t size,
- void *ctx, void *id);
-H5_DLL herr_t H5VL_blob_get(const H5VL_class_t *cls, const void *id, void *ctx,
- void *blob);
-H5_DLL herr_t H5VL_blob_specific(const H5VL_class_t *cls, void *id,
- H5VL_blob_specific_t specific_type, ...);
+H5_DLL herr_t H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, void *blob_id, void *ctx);
+H5_DLL herr_t H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size_t *size, void *ctx);
+H5_DLL herr_t H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specific_t specific_type, ...);
/* Generic functions */
H5_DLL herr_t H5VL_optional(const H5VL_object_t *vol_obj, hid_t dxpl_id,void **req, ...);
diff --git a/src/H5trace.c b/src/H5trace.c
index b1301dd..e209995 100644
--- a/src/H5trace.c
+++ b/src/H5trace.c
@@ -2592,6 +2592,35 @@ H5_trace(const double *returning, const char *func, const char *type, ...)
} /* end switch */
} /* end else */
break;
+ case 'B':
+ if(ptr) {
+ if(vp)
+ HDfprintf (out, "0x%lx", (unsigned long)vp);
+ else
+ HDfprintf(out, "NULL");
+ } /* end if */
+ else {
+ H5VL_blob_specific_t specific = (H5VL_blob_specific_t)HDva_arg(ap, int);
+
+ switch(specific) {
+ case H5VL_BLOB_DELETE:
+ HDfprintf(out, "H5VL_BLOB_DELETE");
+ break;
+ case H5VL_BLOB_GETSIZE:
+ HDfprintf(out, "H5VL_BLOB_GETSIZE");
+ break;
+ case H5VL_BLOB_ISNULL:
+ HDfprintf(out, "H5VL_BLOB_ISNULL");
+ break;
+ case H5VL_BLOB_SETNULL:
+ HDfprintf(out, "H5VL_BLOB_SETNULL");
+ break;
+ default:
+ HDfprintf(out, "%ld", (long)specific);
+ break;
+ } /* end switch */
+ } /* end else */
+ break;
case 'C':
if(ptr) {
if(vp)