summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt12
-rw-r--r--src/H5.c1
-rw-r--r--src/H5Edefin.h1
-rw-r--r--src/H5Einit.h5
-rw-r--r--src/H5Epubgen.h2
-rw-r--r--src/H5Eterm.h1
-rw-r--r--src/H5Ipublic.h1
-rw-r--r--src/H5Q.c1214
-rw-r--r--src/H5Qprivate.h100
-rw-r--r--src/H5Qpublic.h83
-rw-r--r--src/H5Tnative.c4
-rw-r--r--src/H5Tprivate.h4
-rw-r--r--src/H5err.txt1
-rw-r--r--src/H5private.h1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/hdf5.h1
-rw-r--r--testff/CMakeLists.txt2
-rw-r--r--testff/h5ff_query.c152
18 files changed, 1584 insertions, 3 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 84c32f0..a891f83 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -490,6 +490,14 @@ SET (H5PL_HDRS
)
IDE_GENERATED_PROPERTIES ("H5PL" "${H5PL_HDRS}" "${H5PL_SRCS}" )
+SET (H5Q_SRCS
+ ${HDF5_SRC_DIR}/H5Q.c
+)
+
+SET (H5Q_HDRS
+ ${HDF5_SRC_DIR}/H5Qpublic.h
+)
+IDE_GENERATED_PROPERTIES ("H5Q" "${H5Q_HDRS}" "${H5Q_SRCS}" )
SET (H5R_SRCS
${HDF5_SRC_DIR}/H5R.c
@@ -659,6 +667,7 @@ IF (HDF5_ENABLE_EFF)
${HDF5_SRC_DIR}/H5VLiod_map.c
${HDF5_SRC_DIR}/H5VLiod_trans.c
${HDF5_SRC_DIR}/H5VLiod_encdec.c
+ ${HDF5_SRC_DIR}/H5VLiod_analysis.c
)
SET (H5VL_HDRS
${H5VL_HDRS}
@@ -728,6 +737,7 @@ SET (common_SRCS
${H5O_SRCS}
${H5P_SRCS}
${H5PL_SRCS}
+ ${H5Q_SRCS}
${H5R_SRCS}
${H5UC_SRCS}
${H5RS_SRCS}
@@ -775,6 +785,7 @@ SET (H5_PUBLIC_HEADERS
${H5O_HDRS}
${H5P_HDRS}
${H5PL_HDRS}
+ ${H5Q_HDRS}
${H5R_HDRS}
${H5S_HDRS}
${H5SM_HDRS}
@@ -821,6 +832,7 @@ SET (H5_PRIVATE_HEADERS
${HDF5_SRC_DIR}/H5Oprivate.h
${HDF5_SRC_DIR}/H5Pprivate.h
${HDF5_SRC_DIR}/H5PLprivate.h
+ ${HDF5_SRC_DIR}/H5Qprivate.h
${HDF5_SRC_DIR}/H5UCprivate.h
${HDF5_SRC_DIR}/H5Rprivate.h
${HDF5_SRC_DIR}/H5RSprivate.h
diff --git a/src/H5.c b/src/H5.c
index 1a474db..a1bfbf8 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -262,6 +262,7 @@ H5_term_library(void)
pending += DOWN(TR);
pending += DOWN(RC);
pending += DOWN(ES);
+ pending += DOWN(Q);
/* Don't shut down the file code until objects in files are shut down */
if(pending == 0)
diff --git a/src/H5Edefin.h b/src/H5Edefin.h
index 4c4b4df..1f0d86a 100644
--- a/src/H5Edefin.h
+++ b/src/H5Edefin.h
@@ -40,6 +40,7 @@ hid_t H5E_ATTR_g = FAIL; /* Attribute */
hid_t H5E_IO_g = FAIL; /* Low-level I/O */
hid_t H5E_EFL_g = FAIL; /* External file list */
hid_t H5E_TST_g = FAIL; /* Ternary Search Trees */
+hid_t H5E_QUERY_g = FAIL; /* Query */
hid_t H5E_FSPACE_g = FAIL; /* Free Space Manager */
hid_t H5E_DATASET_g = FAIL; /* Dataset */
hid_t H5E_STORAGE_g = FAIL; /* Data storage */
diff --git a/src/H5Einit.h b/src/H5Einit.h
index 75c0b70..8a2c144 100644
--- a/src/H5Einit.h
+++ b/src/H5Einit.h
@@ -119,6 +119,11 @@ if((msg = H5E_create_msg(cls, H5E_MAJOR, "Ternary Search Trees"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_TST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_QUERY_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MAJOR, "Query"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_QUERY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
assert(H5E_FSPACE_g==(-1));
if((msg = H5E_create_msg(cls, H5E_MAJOR, "Free Space Manager"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h
index e5ecd10..f0d4242 100644
--- a/src/H5Epubgen.h
+++ b/src/H5Epubgen.h
@@ -43,6 +43,7 @@
#define H5E_IO (H5OPEN H5E_IO_g)
#define H5E_EFL (H5OPEN H5E_EFL_g)
#define H5E_TST (H5OPEN H5E_TST_g)
+#define H5E_QUERY (H5OPEN H5E_QUERY_g)
#define H5E_FSPACE (H5OPEN H5E_FSPACE_g)
#define H5E_DATASET (H5OPEN H5E_DATASET_g)
#define H5E_STORAGE (H5OPEN H5E_STORAGE_g)
@@ -77,6 +78,7 @@ H5_DLLVAR hid_t H5E_ATTR_g; /* Attribute */
H5_DLLVAR hid_t H5E_IO_g; /* Low-level I/O */
H5_DLLVAR hid_t H5E_EFL_g; /* External file list */
H5_DLLVAR hid_t H5E_TST_g; /* Ternary Search Trees */
+H5_DLLVAR hid_t H5E_QUERY_g; /* Query */
H5_DLLVAR hid_t H5E_FSPACE_g; /* Free Space Manager */
H5_DLLVAR hid_t H5E_DATASET_g; /* Dataset */
H5_DLLVAR hid_t H5E_STORAGE_g; /* Data storage */
diff --git a/src/H5Eterm.h b/src/H5Eterm.h
index aecef3e..de0db21 100644
--- a/src/H5Eterm.h
+++ b/src/H5Eterm.h
@@ -41,6 +41,7 @@ H5E_ATTR_g=
H5E_IO_g=
H5E_EFL_g=
H5E_TST_g=
+H5E_QUERY_g=
H5E_FSPACE_g=
H5E_DATASET_g=
H5E_STORAGE_g=
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index 1ca0a91..0c38ff3 100644
--- a/src/H5Ipublic.h
+++ b/src/H5Ipublic.h
@@ -49,6 +49,7 @@ typedef enum H5I_type_t {
H5I_ES, /*type ID for Event Queue objects */
H5I_RC, /*type ID for Read Context objects */
H5I_TR, /*type ID for Transaction objects */
+ H5I_QUERY, /*type ID for Query objects */
H5I_GENPROP_CLS, /*type ID for generic property list classes */
H5I_GENPROP_LST, /*type ID for generic property lists */
H5I_ERROR_CLASS, /*type ID for error classes */
diff --git a/src/H5Q.c b/src/H5Q.c
new file mode 100644
index 0000000..b754103
--- /dev/null
+++ b/src/H5Q.c
@@ -0,0 +1,1214 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: Query routines.
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5Q_init_interface
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Qprivate.h" /* Query */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h"
+
+/****************/
+/* Local Macros */
+/****************/
+#define H5Q_TYPE_SEQ \
+ ((H5T_NATIVE_CHAR)(char))\
+ ((H5T_NATIVE_SHORT)(short)) \
+ ((H5T_NATIVE_INT)(int)) \
+ ((H5T_NATIVE_LONG)(long)) \
+ ((H5T_NATIVE_LLONG)(long long)) \
+ ((H5T_NATIVE_FLOAT)(float)) \
+ ((H5T_NATIVE_DOUBLE)(double))
+
+#define H5Q_APPLY_MATCH_OP(result, op, x, y) \
+ switch (op) { \
+ case H5Q_MATCH_EQUAL: \
+ result = (x == y); \
+ break; \
+ case H5Q_MATCH_NOT_EQUAL: \
+ result = (x != y); \
+ break; \
+ case H5Q_MATCH_LESS_THAN: \
+ result = (x < y); \
+ break; \
+ case H5Q_MATCH_GREATER_THAN: \
+ result = (x > y); \
+ break; \
+ default: \
+ break; \
+ }
+
+#define H5Q_CMP_DATA_ELEM(result, op, type, x, y) \
+{ \
+ type x_value; \
+ type y_value; \
+ x_value = *((type *) x); \
+ y_value = *((type *) y); \
+ \
+ H5Q_APPLY_MATCH_OP(result, op, x_value, y_value) \
+}
+
+#define H5Q_CMP_TYPE(type1, type2, native_type) \
+ (0 == H5T_cmp(type1, native_type, FALSE)) || \
+ (0 == H5T_cmp(type2, native_type, FALSE))
+
+/******************/
+/* Local Typedefs */
+/******************/
+typedef enum H5Q_match_type_t { /* The different kinds of native types we can match */
+ H5Q_NATIVE_INT_MATCH_CHAR,
+ H5Q_NATIVE_INT_MATCH_SHORT,
+ H5Q_NATIVE_INT_MATCH_INT,
+ H5Q_NATIVE_INT_MATCH_LONG,
+ H5Q_NATIVE_INT_MATCH_LLONG,
+ H5Q_NATIVE_FLOAT_MATCH_FLOAT,
+ H5Q_NATIVE_FLOAT_MATCH_DOUBLE
+} H5Q_match_type_t;
+
+/********************/
+/* Local Prototypes */
+/********************/
+static herr_t H5Q_apply_combine(H5Q_t *query, hbool_t *result, H5T_t *type,
+ const void *elem);
+static herr_t H5Q_apply_select(H5Q_t *query, hbool_t *result, H5T_t *type,
+ const void *elem);
+static herr_t H5Q_apply_data_elem(H5Q_t *query, hbool_t *result, H5T_t *type,
+ const void *elem);
+static herr_t H5Q_apply_attr_name(H5Q_t *query, hbool_t *result,
+ const char *name);
+static herr_t H5Q_apply_link_name(H5Q_t *query, hbool_t *result,
+ const char *name);
+
+static H5_inline void
+H5Q_encode_memcpy(unsigned char **buf_ptr, size_t *nalloc, const void *data,
+ size_t data_size)
+{
+ if (*buf_ptr != NULL) {
+ HDmemcpy(*buf_ptr, data, data_size);
+ *buf_ptr += data_size;
+ }
+ *nalloc += data_size;
+}
+
+static H5_inline void
+H5Q_decode_memcpy(void *data, size_t data_size, const unsigned char **buf_ptr)
+{
+ if (*buf_ptr != NULL) {
+ HDmemcpy(data, *buf_ptr, data_size);
+ *buf_ptr += data_size;
+ }
+}
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Declare a free list to manage the H5Q_t struct */
+H5FL_DEFINE(H5Q_t);
+
+/* Query ID class */
+static const H5I_class_t H5I_QUERY_CLS[1] = {{
+ H5I_QUERY, /* Class ID for the type */
+ 0, /* Class behavior flags */
+ 0, /* Number of reserved IDs for this type */
+ (H5I_free_t)H5Q_close, /* Free function for object's of this type */
+ NULL /* Free function for auxilary objects of this type */
+}};
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Q_init(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+ /* FUNC_ENTER() does all the work */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_init() */
+
+/*--------------------------------------------------------------------------
+NAME
+ H5Q_init_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5Q_init_interface()
+
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines.
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5Q_init_interface(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Initialize the atom group for the QUERY IDs */
+ if (H5I_register_type(H5I_QUERY_CLS) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTINIT, FAIL, "unable to initialize interface")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_init_interface() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Q_term_interface
+ PURPOSE
+ Terminate various H5Q objects
+ USAGE
+ void H5Q_term_interface()
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Release the atom group and any other resources allocated.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Can't report errors...
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+int
+H5Q_term_interface(void)
+{
+ int n = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if (H5_interface_initialize_g) {
+ if ((n = H5I_nmembers(H5I_QUERY))) {
+ H5I_clear_type(H5I_QUERY, FALSE, FALSE);
+ } /* end if */
+ else {
+ /* Free data types */
+ H5I_dec_type_ref(H5I_QUERY);
+
+ /* Shut down interface */
+ H5_interface_initialize_g = 0;
+ n = 1; /* H5I */
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* end H5Q_term_interface() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qcreate
+ *
+ * Purpose: Create a new query object of query_type type, with match_op
+ * determining the query's match condition and additional parameters
+ * determined by the type of the query.
+ *
+ * Return: Success: The ID for a new query.
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Qcreate(H5Q_type_t query_type, H5Q_match_op_t match_op, ...)
+{
+ H5Q_t *query = NULL;
+ va_list ap;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+
+ va_start(ap, match_op);
+
+ switch (query_type) {
+ case H5Q_TYPE_DATA_ELEM:
+ {
+ H5T_t *datatype = NULL;
+ hid_t datatype_id;
+ const void *value;
+
+ /* Get arguments */
+ datatype_id = va_arg(ap, hid_t);
+ value = va_arg(ap, const void *);
+
+ /* Get type */
+ if (NULL == (datatype = (H5T_t *) H5I_object_verify(datatype_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+
+ /* Create a new query object */
+ if (NULL == (query = H5Q_create(query_type, match_op, datatype, value)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCREATE, FAIL, "unable to create query")
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ const char *attr_name;
+
+ /* Get arguments */
+ attr_name = va_arg(ap, const char *);
+
+ /* Create a new query object */
+ if (NULL == (query = H5Q_create(query_type, match_op, attr_name)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCREATE, FAIL, "unable to create query")
+ }
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ {
+ const char *link_name;
+
+ /* Get arguments */
+ link_name = va_arg(ap, const char *);
+
+ /* Create a new query object */
+ if (NULL == (query = H5Q_create(query_type, match_op, link_name)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCREATE, FAIL, "unable to create query")
+ }
+ break;
+ default:
+ {
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type")
+ }
+ break;
+ }
+
+ va_end(ap);
+
+ /* Register the new query object to get an ID for it */
+ if ((ret_value = H5I_register(H5I_QUERY, query, TRUE)) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTREGISTER, FAIL, "can't register query handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qcreate() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_create
+ *
+ * Purpose: Private function for H5Qcreate
+ *
+ * Return: Success: Pointer to the new query
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+H5Q_t *
+H5Q_create(H5Q_type_t query_type, H5Q_match_op_t match_op, ...)
+{
+ H5Q_t *query = NULL;
+ va_list ap;
+ H5Q_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ va_start(ap, match_op);
+
+ /* Allocate query struct */
+ if (NULL == (query = H5FL_CALLOC(H5Q_t)))
+ HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, NULL, "can't allocate query structure")
+
+ query->is_combined = FALSE;
+ query->ref_count = 1;
+ query->select.type = query_type;
+ query->select.match_op = match_op;
+ switch (query_type) {
+ case H5Q_TYPE_DATA_ELEM:
+ {
+ H5T_t *datatype = NULL;
+ H5T_t *native_datatype = NULL;
+ size_t datatype_size;
+ const void *value;
+ void *value_buf = NULL;
+
+ datatype = va_arg(ap, H5T_t*);
+ value = va_arg(ap, const void *);
+
+ /* Only use native type */
+ if (NULL == (native_datatype = H5T_get_native_type(datatype, H5T_DIR_DEFAULT, NULL, NULL, NULL)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve native type")
+ query->select.data_elem.type = native_datatype;
+ if (0 == (datatype_size = H5T_get_size(native_datatype)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid size")
+ query->select.data_elem.type_size = datatype_size;
+ if (NULL == (value_buf = H5MM_malloc(datatype_size)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, NULL,
+ "can't allocate value buffer")
+ HDmemcpy(value_buf, value, datatype_size);
+ query->select.data_elem.value = value_buf;
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ const char *attr_name;
+
+ attr_name = va_arg(ap, const char *);
+ query->select.attr_name.name = H5MM_strdup(attr_name);
+ }
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ {
+ const char *link_name;
+
+ link_name = va_arg(ap, const char *);
+ query->select.link_name.name = H5MM_strdup(link_name);
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, NULL, "unsupported/unrecognized query type")
+ break;
+ } /* end switch */
+
+ va_end(ap);
+
+ /* set return value */
+ ret_value = query;
+
+done:
+ if (!ret_value && query)
+ query = H5FL_FREE(H5Q_t, query);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_create() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qclose
+ *
+ * Purpose: Close a query object.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Qclose(hid_t query_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Check args */
+ if (NULL == H5I_object_verify(query_id, H5I_QUERY))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+
+ if (H5I_dec_app_ref(query_id) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTDEC, FAIL, "unable to decrement ref count on query");
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qclose() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_close
+ *
+ * Purpose: Private function for H5Qclose.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Q_close(H5Q_t *query)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ HDassert(query);
+
+ query->ref_count--;
+ if (query->ref_count) HGOTO_DONE(SUCCEED)
+
+ if (query->is_combined) {
+ if (FAIL == H5Q_close(query->combine.l_query))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTFREE, FAIL, "unable to free query")
+ query->combine.l_query = NULL;
+ if (FAIL == H5Q_close(query->combine.r_query))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTFREE, FAIL, "unable to free query")
+ query->combine.r_query = NULL;
+ } else {
+ switch (query->select.type) {
+ case H5Q_TYPE_DATA_ELEM:
+ if (FAIL == H5T_close(query->select.data_elem.type))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTFREE, FAIL, "unable to free datatype");
+ query->select.data_elem.type = NULL;
+ H5MM_free(query->select.data_elem.value);
+ query->select.data_elem.value = NULL;
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ H5MM_free(query->select.attr_name.name);
+ query->select.attr_name.name = NULL;
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ H5MM_free(query->select.link_name.name);
+ query->select.link_name.name = NULL;
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type")
+ break;
+ }
+ }
+
+ /* Free the query struct */
+ query = H5FL_FREE(H5Q_t, query);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_close() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qcombine
+ *
+ * Purpose: Combine query objects to create a new query object.
+ *
+ * Return: Success: The ID for a new combined query.
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Qcombine(hid_t query_id1, H5Q_combine_op_t combine_op, hid_t query_id2)
+{
+ H5Q_t *query = NULL, *query1 = NULL, *query2 = NULL;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Check args and get the query objects */
+ if(NULL == (query1 = (H5Q_t *) H5I_object_verify(query_id1, H5I_QUERY)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+ if(NULL == (query2 = (H5Q_t *) H5I_object_verify(query_id2, H5I_QUERY)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+
+ /* Combine query objects */
+ if (NULL == (query = H5Q_combine(query1, combine_op, query2)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCREATE, FAIL, "unable to combine query objects")
+
+ /* Register the new query object to get an ID for it */
+ if ((ret_value = H5I_register(H5I_QUERY, query, TRUE)) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTREGISTER, FAIL, "can't register query handle")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qcombine() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_combine
+ *
+ * Purpose: Private function for H5Qcombine.
+ *
+ * Return: Success: Pointer to the new query
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+H5Q_t *
+H5Q_combine(H5Q_t *query1, H5Q_combine_op_t combine_op, H5Q_t *query2)
+{
+ H5Q_t *query = NULL;
+ H5Q_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Allocate query struct */
+ if (NULL == (query = H5FL_CALLOC(H5Q_t)))
+ HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, NULL, "can't allocate query structure")
+
+ switch (combine_op) {
+ case H5Q_COMBINE_AND:
+ case H5Q_COMBINE_OR:
+ query->combine.op = combine_op;
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, NULL, "unsupported/unrecognized combine op")
+ break;
+ }
+ query->is_combined = TRUE;
+ query->ref_count = 1;
+ query->combine.l_query = query1;
+ query1->ref_count++;
+ query->combine.r_query = query2;
+ query2->ref_count++;
+
+ /* set return value */
+ ret_value = query;
+
+done:
+ if (!ret_value && query)
+ query = H5FL_FREE(H5Q_t, query);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_combine() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qapply
+ *
+ * Purpose: Apply a query to an element elem of type type_id.
+ * TODO modify prototype for attr/link name support
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Qapply(hid_t query_id, hbool_t *result, hid_t type_id, const void *elem)
+{
+ H5Q_t *query = NULL;
+ H5T_t *type = NULL, *native_type = NULL;
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Check args and get the query objects */
+ if (!result)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL pointer for result")
+ if (NULL == (query = (H5Q_t *) H5I_object_verify(query_id, H5I_QUERY)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+ if(NULL == (type = (H5T_t *) H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+
+ /* Only use native type */
+ if (NULL == (native_type = H5T_get_native_type(type, H5T_DIR_DEFAULT, NULL, NULL, NULL)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot retrieve native type")
+
+ /* Apply query */
+ if (FAIL == (ret_value = H5Q_apply(query, result, native_type, elem)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query")
+
+done:
+ if (native_type)
+ H5T_close(native_type);
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qapply() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply
+ *
+ * Purpose: Private function for H5Qapply.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Q_apply(H5Q_t *query, hbool_t *result, H5T_t *type, const void *elem)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(query);
+ HDassert(result);
+
+ if (query->is_combined) {
+ if (FAIL == (ret_value = H5Q_apply_combine(query, result, type, elem)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query")
+ } else {
+ if (FAIL == (ret_value = H5Q_apply_select(query, result, type, elem)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply_combine
+ *
+ * Purpose: Private function for H5Qapply (combine query).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q_apply_combine(H5Q_t *query, hbool_t *result, H5T_t *type, const void *elem)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t result1, result2;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(query);
+ HDassert(query->is_combined == TRUE);
+
+ if (FAIL == H5Q_apply(query->combine.l_query, &result1, type, elem))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query")
+ if (FAIL == H5Q_apply(query->combine.r_query, &result2, type, elem))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply query")
+
+ switch (query->combine.op) {
+ case H5Q_COMBINE_AND:
+ *result = result1 && result2;
+ break;
+ case H5Q_COMBINE_OR:
+ *result = result1 || result2;
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized combine op")
+ break;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply_combine() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply_select
+ *
+ * Purpose: Private function for H5Qapply (select query).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q_apply_select(H5Q_t *query, hbool_t *result, H5T_t *type, const void *elem)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(query);
+ HDassert(query->is_combined == FALSE);
+
+ switch (query->select.type) {
+ case H5Q_TYPE_DATA_ELEM:
+ if (FAIL == (ret_value = H5Q_apply_data_elem(query, result, type, elem)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply data element query")
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ /* TODO pass non NULL string */
+ if (FAIL == (ret_value = H5Q_apply_attr_name(query, result, NULL)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply attribute name query")
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ /* TODO pass non NULL string */
+ if (FAIL == (ret_value = H5Q_apply_link_name(query, result, NULL)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCOMPARE, FAIL, "unable to apply link name query")
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type")
+ break;
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply_select() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_promote_type
+ *
+ * Purpose: Private function for H5Qapply (promote data element type
+ * so that data element and query element can be compared).
+ *
+ * Return: Success: Pointer to promoted native type
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_t *
+H5Q_promote_type(H5T_t *type1, H5T_t *type2, H5Q_match_type_t *match_type)
+{
+ H5T_t *ret_value; /* Return value */
+ H5T_class_t type1_class, type2_class, promoted_type_class;
+ H5T_t *promoted_type;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Get class of types */
+ if (H5T_NO_CLASS == (type1_class = H5T_get_class(type1, FALSE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class")
+ if (H5T_NO_CLASS == (type2_class = H5T_get_class(type2, FALSE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class")
+
+ if ((type1_class == H5T_FLOAT) || (type2_class == H5T_FLOAT)) {
+ promoted_type_class = H5T_FLOAT;
+ } else {
+ promoted_type_class = H5T_INTEGER;
+ }
+
+ switch (promoted_type_class) {
+ case H5T_INTEGER:
+ if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_LLONG_g))) {
+ *match_type = H5Q_NATIVE_INT_MATCH_LLONG;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_LLONG_g);
+ } else if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_LONG_g))) {
+ *match_type = H5Q_NATIVE_INT_MATCH_LONG;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_LONG_g);
+ } else if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_INT_g))) {
+ *match_type = H5Q_NATIVE_INT_MATCH_INT;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_INT_g);
+ } else if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_SHORT_g))) {
+ *match_type = H5Q_NATIVE_INT_MATCH_SHORT;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_SHORT_g);
+ } else if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_SCHAR_g))) {
+ *match_type = H5Q_NATIVE_INT_MATCH_CHAR;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_SCHAR_g);
+ } else {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid type")
+ }
+ break;
+ case H5T_FLOAT:
+ if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_DOUBLE_g))) {
+ *match_type = H5Q_NATIVE_FLOAT_MATCH_DOUBLE;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_DOUBLE_g);
+ } else if (H5Q_CMP_TYPE(type1, type2, (H5T_t *)H5I_object(H5T_NATIVE_FLOAT_g))) {
+ *match_type = H5Q_NATIVE_FLOAT_MATCH_FLOAT;
+ promoted_type = (H5T_t *)H5I_object(H5T_NATIVE_FLOAT_g);
+ } else {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid type")
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class")
+ break;
+ }
+
+ ret_value = promoted_type;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_promote_type() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply_data_elem
+ *
+ * Purpose: Private function for H5Qapply (data element).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q_apply_data_elem(H5Q_t *query, hbool_t *result, H5T_t *type, const void *value)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+ void *value_buf = NULL, *query_value_buf = NULL;
+ H5T_t *query_type, *promoted_type;
+ H5Q_match_type_t match_type;
+ size_t type_size, query_type_size, promoted_type_size;
+ hid_t type_id, query_type_id, promoted_type_id;
+ H5T_path_t *tpath;
+ H5Q_match_op_t query_op;
+ hbool_t query_result = FALSE;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(query);
+ HDassert(query->select.type == H5Q_TYPE_DATA_ELEM);
+
+ /* Keep a copy of elem to work on */
+ if (0 == (type_size = H5T_get_size(type)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid size")
+
+ /* Keep a copy of the query value */
+ query_type = query->select.data_elem.type;
+ query_type_size = query->select.data_elem.type_size;
+ query_op = query->select.match_op;
+
+ /* Promote type to compare elements with query */
+ promoted_type = H5Q_promote_type(type, query_type, &match_type);
+ if (0 == (promoted_type_size = H5T_get_size(promoted_type)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid size")
+
+ /* Resize value and query value buf for convert
+ * (promoted_type_size is always bigger) */
+ if (NULL == (value_buf = H5MM_malloc(promoted_type_size)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate value buffer")
+ HDmemcpy(value_buf, value, type_size);
+
+ if (NULL == (query_value_buf = H5MM_malloc(promoted_type_size)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, FAIL, "can't allocate value buffer")
+ HDmemcpy(query_value_buf, query->select.data_elem.value, query_type_size);
+
+ /* Create temporary IDs for H5T_convert */
+ type_id = H5I_register(H5I_DATATYPE, type, FALSE);
+ query_type_id = H5I_register(H5I_DATATYPE, query_type, FALSE);
+ promoted_type_id = H5I_register(H5I_DATATYPE, promoted_type, FALSE);
+
+ /* Find the conversion function */
+ if (NULL == (tpath = H5T_path_find(type, promoted_type, NULL, NULL, H5P_LST_DATASET_XFER_g, FALSE)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTINIT, FAIL, "unable to find type info")
+ if (FAIL == (H5T_convert(tpath, type_id, promoted_type_id, 1, (size_t)0, (size_t)0, value_buf, NULL, H5P_LST_DATASET_XFER_g)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCONVERT, FAIL, "can't convert value")
+
+ if (NULL == (tpath = H5T_path_find(query_type, promoted_type, NULL, NULL, H5P_LST_DATASET_XFER_g, FALSE)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTINIT, FAIL, "unable to find type info")
+ if (FAIL == (H5T_convert(tpath, query_type_id, promoted_type_id, 1, (size_t)0, (size_t)0, query_value_buf, NULL, H5P_LST_DATASET_XFER_g)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTCONVERT, FAIL, "can't convert query value")
+
+ /* Could also use BOOST preprocessor for that but not really nice */
+ switch (match_type) {
+ case H5Q_NATIVE_INT_MATCH_CHAR:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, char, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_INT_MATCH_SHORT:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, short, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_INT_MATCH_INT:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, int, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_INT_MATCH_LONG:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, long, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_INT_MATCH_LLONG:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, long long, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_FLOAT_MATCH_FLOAT:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, float, value_buf, query_value_buf);
+ break;
+ case H5Q_NATIVE_FLOAT_MATCH_DOUBLE:
+ H5Q_CMP_DATA_ELEM(query_result, query_op, double, value_buf, query_value_buf);
+ break;
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "unsupported/unrecognized datatype")
+ break;
+ }
+
+ *result = query_result;
+
+done:
+ H5MM_free(value_buf);
+ H5MM_free(query_value_buf);
+
+ /* Free temporary IDs */
+ H5I_remove(type_id);
+ H5I_remove(query_type_id);
+ H5I_remove(promoted_type_id);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply_data_elem() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply_attr_name
+ *
+ * Purpose: Private function for H5Qapply (attribute name).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q_apply_attr_name(H5Q_t *query, hbool_t *result, const char *name)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(query);
+ HDassert(query->select.type == H5Q_TYPE_ATTR_NAME);
+
+ *result = (0 == HDstrcmp(name, query->select.attr_name.name));
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply_attr_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_apply_link_name
+ *
+ * Purpose: Private function for H5Qapply (link name).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Q_apply_link_name(H5Q_t *query, hbool_t *result, const char *name)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(query);
+ HDassert(query->select.type == H5Q_TYPE_LINK_NAME);
+
+ *result = (0 == HDstrcmp(name, query->select.link_name.name));
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_apply_link_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qencode
+ *
+ * Purpose: Given a query ID, serialize the query into buf.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Qencode(hid_t query_id, void *buf, size_t *nalloc)
+{
+ H5Q_t *query;
+ herr_t ret_value;
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Check argument and retrieve object */
+ if(NULL == (query = (H5Q_t *)H5I_object_verify(query_id, H5I_QUERY)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a query ID")
+ if(nalloc == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL pointer for buffer size")
+
+ /* Encode the query */
+ if((ret_value = H5Q_encode(query, (unsigned char *)buf, nalloc)) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTENCODE, FAIL, "can't encode query")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qencode() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_encode
+ *
+ * Purpose: Private function for H5Qencode.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Q_encode(H5Q_t *query, unsigned char *buf, size_t *nalloc)
+{
+ size_t buf_size = 0;
+ herr_t ret_value = SUCCEED;
+ unsigned char *buf_ptr = buf;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(query);
+ HDassert(nalloc);
+
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &query->is_combined, sizeof(hbool_t));
+ if (query->is_combined) {
+ size_t l_buf_size = 0, r_buf_size = 0;
+
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &query->combine.op, sizeof(H5Q_combine_op_t));
+ H5Q_encode(query->combine.l_query, buf_ptr, &l_buf_size);
+ buf_size += l_buf_size;
+ if (buf_ptr) buf_ptr += l_buf_size;
+ H5Q_encode(query->combine.r_query, buf_ptr, &r_buf_size);
+ buf_size += r_buf_size;
+ if (buf_ptr) buf_ptr += r_buf_size;
+ } else {
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &query->select.type, sizeof(H5Q_type_t));
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &query->select.match_op, sizeof(H5Q_match_op_t));
+ switch (query->select.type) {
+ case H5Q_TYPE_DATA_ELEM:
+ {
+ size_t type_id_nalloc = 0;
+ H5T_t *type = query->select.data_elem.type;
+ size_t type_size = query->select.data_elem.type_size;
+ void *value_buf = query->select.data_elem.value;
+
+ if (FAIL == H5T_encode(type, NULL, &type_id_nalloc))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTENCODE, FAIL, "can't get encoding size for datatype");
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &type_id_nalloc, sizeof(size_t));
+ if (FAIL == H5T_encode(type, buf_ptr, &type_id_nalloc))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTENCODE, FAIL, "can't encode datatype");
+ buf_size += type_id_nalloc;
+ if (buf_ptr) buf_ptr += type_id_nalloc;
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &type_size, sizeof(size_t));
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, value_buf, type_size);
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ size_t name_len = HDstrlen(query->select.attr_name.name) + 1;
+ char *name = query->select.attr_name.name;
+
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &name_len, sizeof(size_t));
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, name, name_len);
+ }
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ {
+ size_t name_len = HDstrlen(query->select.link_name.name) + 1;
+ char *name = query->select.attr_name.name;
+
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, &name_len, sizeof(size_t));
+ H5Q_encode_memcpy(&buf_ptr, &buf_size, name, name_len);
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, FAIL, "unsupported/unrecognized query type")
+ break;
+ }
+ }
+
+ *nalloc = buf_size;
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_encode() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Qdecode
+ *
+ * Purpose: Deserialize the buffer and return a new query handle.
+ *
+ * Return: Success: query ID (non-negative)
+ *
+ * Failure: negative
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Qdecode(const void *buf)
+{
+ H5Q_t *query;
+ hid_t ret_value; /* Return value */
+ const unsigned char *buf_ptr = (const unsigned char *) buf;
+
+ FUNC_ENTER_API(FAIL)
+
+ /* Check args */
+ if(buf == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "empty buffer")
+
+ /* Create datatype by decoding buffer */
+ if(NULL == (query = H5Q_decode(&buf_ptr)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTDECODE, FAIL, "can't decode object")
+
+ /* Register the type and return the ID */
+ if((ret_value = H5I_register(H5I_QUERY, query, TRUE)) < 0)
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTREGISTER, FAIL, "unable to register query")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Qdecode() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Q_decode
+ *
+ * Purpose: Private function for H5Qdecode.
+ *
+ * Return: Success: Pointer to the decoded query
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+H5Q_t *
+H5Q_decode(const unsigned char **buf_ptr)
+{
+ H5Q_t *ret_value = NULL;
+ H5Q_t *query = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(*buf_ptr);
+
+ /* Allocate query struct */
+ if (NULL == (query = H5FL_CALLOC(H5Q_t)))
+ HGOTO_ERROR(H5E_QUERY, H5E_NOSPACE, NULL, "can't allocate query structure")
+
+ /* Set ref count */
+ query->ref_count = 1;
+
+ H5Q_decode_memcpy(&query->is_combined, sizeof(hbool_t), buf_ptr);
+ if (query->is_combined) {
+ H5Q_decode_memcpy(&query->combine.op, sizeof(H5Q_combine_op_t), buf_ptr);
+ query->combine.l_query = H5Q_decode(buf_ptr);
+ query->combine.r_query = H5Q_decode(buf_ptr);
+ } else {
+ H5Q_decode_memcpy(&query->select.type, sizeof(H5Q_type_t), buf_ptr);
+ H5Q_decode_memcpy(&query->select.match_op, sizeof(H5Q_match_op_t), buf_ptr);
+ switch (query->select.type) {
+ case H5Q_TYPE_DATA_ELEM:
+ {
+ size_t type_id_nalloc = 0;
+ H5T_t *type;
+ size_t type_size;
+ void *value_buf;
+
+ H5Q_decode_memcpy(&type_id_nalloc, sizeof(size_t), buf_ptr);
+ if (NULL == (type = H5T_decode(*buf_ptr)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode datatype");
+ query->select.data_elem.type = type;
+ *buf_ptr += type_id_nalloc;
+
+ H5Q_decode_memcpy(&type_size, sizeof(size_t), buf_ptr);
+ query->select.data_elem.type_size = type_size;
+ if (NULL == (value_buf = H5MM_malloc(type_size)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, NULL, "can't allocate value buffer")
+ H5Q_decode_memcpy(value_buf, type_size, buf_ptr);
+ query->select.data_elem.value = value_buf;
+ }
+ break;
+ case H5Q_TYPE_ATTR_NAME:
+ {
+ size_t name_len;
+ char *name;
+
+ H5Q_decode_memcpy(&name_len, sizeof(size_t), buf_ptr);
+ if (NULL == (name = H5MM_malloc(name_len)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, NULL,
+ "can't allocate value buffer")
+ H5Q_decode_memcpy(name, name_len, buf_ptr);
+ query->select.attr_name.name = name;
+ }
+ break;
+ case H5Q_TYPE_LINK_NAME:
+ {
+ size_t name_len;
+ char *name;
+
+ H5Q_decode_memcpy(&name_len, sizeof(size_t), buf_ptr);
+ if (NULL == (name = H5MM_malloc(name_len)))
+ HGOTO_ERROR(H5E_QUERY, H5E_CANTALLOC, NULL,
+ "can't allocate value buffer")
+ H5Q_decode_memcpy(name, name_len, buf_ptr);
+ query->select.link_name.name = name;
+ }
+ break;
+ default:
+ HGOTO_ERROR(H5E_QUERY, H5E_BADTYPE, NULL, "unsupported/unrecognized query type")
+ break;
+ }
+ }
+
+ ret_value = query;
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Q_decode() */
diff --git a/src/H5Qprivate.h b/src/H5Qprivate.h
new file mode 100644
index 0000000..1b6939b
--- /dev/null
+++ b/src/H5Qprivate.h
@@ -0,0 +1,100 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * This file contains private information about the H5Q module
+ */
+#ifndef _H5Qprivate_H
+#define _H5Qprivate_H
+
+/* Include package's public header */
+#include "H5Qpublic.h"
+
+/* Private headers needed by this file */
+#include "H5Tprivate.h"
+
+/**************************/
+/* Library Private Macros */
+/**************************/
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* Data element */
+struct H5Q_data_elem {
+ H5T_t *type; /* type */
+ size_t type_size; /* type size */
+ void *value; /* value */
+};
+
+/* Attribute name */
+struct H5Q_attr_name {
+ char *name; /* name */
+};
+
+/* Link name */
+struct H5Q_link_name {
+ char *name; /* name */
+};
+
+/* Query */
+typedef struct H5Q_t H5Q_t;
+
+/* Combine query */
+struct H5Q_combine {
+ H5Q_combine_op_t op; /* op */
+ H5Q_t *l_query; /* left op query */
+ H5Q_t *r_query; /* right op query */
+};
+
+/* Select query */
+struct H5Q_select {
+ H5Q_type_t type; /* type */
+ H5Q_match_op_t match_op; /* match op */
+ union {
+ struct H5Q_data_elem data_elem;
+ struct H5Q_attr_name attr_name;
+ struct H5Q_link_name link_name;
+ };
+};
+
+/* Query */
+struct H5Q_t {
+ unsigned ref_count; /* ref count */
+ hbool_t is_combined;
+ union {
+ struct H5Q_select select;
+ struct H5Q_combine combine;
+ };
+};
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+/******************************/
+/* Library Private Prototypes */
+/******************************/
+H5_DLL herr_t H5Q_init(void);
+H5_DLL H5Q_t *H5Q_create(H5Q_type_t query_type, H5Q_match_op_t match_op, ...);
+H5_DLL herr_t H5Q_close(H5Q_t *query);
+H5_DLL H5Q_t *H5Q_combine(H5Q_t *query1, H5Q_combine_op_t combine_op, H5Q_t *query2);
+H5_DLL herr_t H5Q_apply(H5Q_t *query, hbool_t *result, H5T_t *type, const void *elem);
+
+H5_DLL herr_t H5Q_encode(H5Q_t *query, unsigned char *buf, size_t *nalloc);
+H5_DLL H5Q_t *H5Q_decode(const unsigned char **buf);
+
+#endif /* _H5Qprivate_H */
diff --git a/src/H5Qpublic.h b/src/H5Qpublic.h
new file mode 100644
index 0000000..f3dd48f
--- /dev/null
+++ b/src/H5Qpublic.h
@@ -0,0 +1,83 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * This file contains function prototypes for each exported function in the
+ * H5Q module.
+ */
+#ifndef _H5Qpublic_H
+#define _H5Qpublic_H
+
+/* Public headers needed by this file */
+#include "H5public.h"
+#include "H5Ipublic.h"
+
+/*****************/
+/* Public Macros */
+/*****************/
+
+
+/*******************/
+/* Public Typedefs */
+/*******************/
+
+/* Query type */
+typedef enum H5Q_type_t {
+ H5Q_TYPE_DATA_ELEM, /* selects data elements */
+ H5Q_TYPE_ATTR_NAME, /* selects attributes */
+ H5Q_TYPE_LINK_NAME /* selects objects */
+} H5Q_type_t;
+
+/* Query match conditions */
+typedef enum H5Q_match_op_t {
+ H5Q_MATCH_EQUAL, /* equal */
+ H5Q_MATCH_NOT_EQUAL, /* not equal */
+ H5Q_MATCH_LESS_THAN, /* less than */
+ H5Q_MATCH_GREATER_THAN /* greater than */
+} H5Q_match_op_t;
+
+/* Query combine operators */
+typedef enum H5Q_combine_op_t {
+ H5Q_COMBINE_AND,
+ H5Q_COMBINE_OR
+} H5Q_combine_op_t;
+
+/********************/
+/* Public Variables */
+/********************/
+
+/*********************/
+/* Public Prototypes */
+/*********************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Function prototypes */
+H5_DLL hid_t H5Qcreate(H5Q_type_t query_type, H5Q_match_op_t match_op, ...);
+H5_DLL herr_t H5Qclose(hid_t query_id);
+H5_DLL hid_t H5Qcombine(hid_t query_id1, H5Q_combine_op_t combine_op, hid_t query_id2);
+H5_DLL herr_t H5Qapply(hid_t query_id, hbool_t *result, hid_t type_id, const void *elem);
+/* or return dataspace and have
+ * hid_t H5Qapply(query_id, result, enum data_elem/link/attr, nelem, void*);
+ */
+
+/* Encode / decode */
+H5_DLL herr_t H5Qencode(hid_t query_id, void *buf, size_t *nalloc);
+H5_DLL hid_t H5Qdecode(const void *buf);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _H5Qpublic_H */
diff --git a/src/H5Tnative.c b/src/H5Tnative.c
index 1a97f39..2dee5f5 100644
--- a/src/H5Tnative.c
+++ b/src/H5Tnative.c
@@ -32,8 +32,6 @@
#include "H5Tpkg.h" /* Datatypes */
/* Static local functions */
-static H5T_t *H5T_get_native_type(H5T_t *dt, H5T_direction_t direction,
- size_t *struct_align, size_t *offset, size_t *comp_size);
static H5T_t *H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction,
size_t *struct_align, size_t *offset, size_t *comp_size);
static H5T_t *H5T_get_native_float(size_t size, H5T_direction_t direction,
@@ -147,7 +145,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static H5T_t *
+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 */
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 217a0d6..7bf21ef 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -166,5 +166,9 @@ H5_DLL int H5T_get_offset(const H5T_t *dt);
/* Fixed-point functions */
H5_DLL H5T_sign_t H5T_get_sign(H5T_t const *dt);
+/* Native type function */
+H5_DLL H5T_t *H5T_get_native_type(H5T_t *dt, H5T_direction_t direction,
+ size_t *struct_align, size_t *offset, size_t *comp_size);
+
#endif /* _H5Tprivate_H */
diff --git a/src/H5err.txt b/src/H5err.txt
index c3908e4..f126066 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -69,6 +69,7 @@ MAJOR, H5E_EFL, External file list
MAJOR, H5E_REFERENCE, References
MAJOR, H5E_VFL, Virtual File Layer
MAJOR, H5E_VOL, Virtual Object Layer
+MAJOR, H5E_QUERY, Query
MAJOR, H5E_TST, Ternary Search Trees
MAJOR, H5E_RS, Reference Counted Strings
MAJOR, H5E_ERROR, Error API
diff --git a/src/H5private.h b/src/H5private.h
index a59662e..0e3df0d 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -2402,6 +2402,7 @@ H5_DLL int H5L_term_interface(void);
H5_DLL int H5M_term_interface(void);
H5_DLL int H5P_term_interface(void);
H5_DLL int H5PL_term_interface(void);
+H5_DLL int H5Q_term_interface(void);
H5_DLL int H5R_term_interface(void);
H5_DLL int H5S_term_interface(void);
H5_DLL int H5T_term_interface(void);
diff --git a/src/Makefile.am b/src/Makefile.am
index 48282fe..8d68f83 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -95,6 +95,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Pgcpl.c H5Pint.c H5Prcapl.c H5Ptrspl.c H5Ptrfpl.c \
H5Plapl.c H5Plcpl.c H5Pocpl.c H5Pocpypl.c H5Pstrcpl.c H5Ptest.c \
H5PL.c \
+ H5Q.c \
H5R.c H5Rdeprec.c \
H5UC.c \
H5RS.c \
@@ -126,6 +127,7 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers
H5Gpublic.h H5Ipublic.h H5Lpublic.h \
H5MMpublic.h H5Opublic.h H5Ppublic.h \
H5PLextern.h \
+ H5Qpublic.h \
H5Rpublic.h H5Spublic.h \
H5Tpublic.h H5Zpublic.h
diff --git a/src/hdf5.h b/src/hdf5.h
index ec05b5b..a8cd527 100644
--- a/src/hdf5.h
+++ b/src/hdf5.h
@@ -36,6 +36,7 @@
#include "H5MMpublic.h" /* Memory management */
#include "H5Opublic.h" /* Object headers */
#include "H5Ppublic.h" /* Property lists */
+#include "H5Qpublic.h" /* Queries */
#include "H5Rpublic.h" /* References */
#include "H5RCpublic.h" /* Read Contexts */
#include "H5Spublic.h" /* Dataspaces */
diff --git a/testff/CMakeLists.txt b/testff/CMakeLists.txt
index c020b25..a522149 100644
--- a/testff/CMakeLists.txt
+++ b/testff/CMakeLists.txt
@@ -65,6 +65,8 @@ ENDMACRO (ADD_H5FF_DRIVER_TEST)
BUILD_H5FF_TEST(hello_server)
BUILD_H5FF_TEST(hello_client)
+BUILD_H5FF_TEST(h5ff_query)
+
# h5ff
# ADD_H5FF_DRIVER_TEST(<target>)
BUILD_H5FF_TEST(h5ff_server)
diff --git a/testff/h5ff_query.c b/testff/h5ff_query.c
new file mode 100644
index 0000000..75e45c3
--- /dev/null
+++ b/testff/h5ff_query.c
@@ -0,0 +1,152 @@
+/*
+ * h5ff_query.c: Test H5Q extensions.
+ */
+
+#include "hdf5.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+static int
+apply(hid_t query)
+{
+ int data_elem1 = 15, data_elem2 = 20, data_elem3 = 25;
+ double data_elem4 = 21.2;
+ float data_elem5 = 17.2f;
+ double data_elem6 = 18.0;
+ double data_elem7 = 2.4;
+ double data_elem8 = 25.0;
+ hbool_t result = 0;
+ int ret = EXIT_SUCCESS;
+
+ H5Qapply(query, &result, H5T_NATIVE_INT, &data_elem1);
+ if (!result) {
+ printf("Data element (%d) does not match query\n", data_elem1);
+ } else {
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+
+ H5Qapply(query, &result, H5T_NATIVE_INT, &data_elem2);
+ if (result) {
+ printf("Data element (%d) matches query\n", data_elem2);
+ } else {
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+
+ H5Qapply(query, &result, H5T_NATIVE_INT, &data_elem3);
+ if (result) {
+ printf("Data element (%d) matches query\n", data_elem3);
+ } else {
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+
+ H5Qapply(query, &result, H5T_NATIVE_DOUBLE, &data_elem4);
+ if (!result) {
+ printf("Data element (%lf) does not match query\n", data_elem4);
+ } else {
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+
+ H5Qapply(query, &result, H5T_NATIVE_FLOAT, &data_elem5);
+ if (result) {
+ printf("Data element (%f) matches query\n", data_elem5);
+ } else {
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+
+ H5Qapply(query, &result, H5T_NATIVE_DOUBLE, &data_elem6);
+ if (result) {
+ printf("Data element (%f) matches query\n", data_elem6);
+ } else {
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+
+ H5Qapply(query, &result, H5T_NATIVE_DOUBLE, &data_elem7);
+ if (!result) {
+ printf("Data element (%f) does not match query\n", data_elem7);
+ } else {
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+
+ H5Qapply(query, &result, H5T_NATIVE_DOUBLE, &data_elem8);
+ if (result) {
+ printf("Data element (%f) matches query\n", data_elem8);
+ } else {
+ ret = EXIT_FAILURE;
+ goto done;
+ }
+
+done:
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int min = 17;
+ int max = 22;
+ double value1 = 21.2;
+ int value2 = 25;
+ hid_t q1, q2, q3, q4, q5, q6, q7, q8;
+ char *buf = NULL;
+ size_t nalloc = 0;
+ int ret = EXIT_SUCCESS;
+
+ /* Create and combine a bunch of queries */
+ q1 = H5Qcreate(H5Q_TYPE_DATA_ELEM, H5Q_MATCH_GREATER_THAN, H5T_NATIVE_INT, &min);
+ q2 = H5Qcreate(H5Q_TYPE_DATA_ELEM, H5Q_MATCH_LESS_THAN, H5T_NATIVE_INT, &max);
+ q3 = H5Qcombine(q1, H5Q_COMBINE_AND, q2);
+ q4 = H5Qcreate(H5Q_TYPE_DATA_ELEM, H5Q_MATCH_NOT_EQUAL, H5T_NATIVE_DOUBLE, &value1);
+ q5 = H5Qcombine(q3, H5Q_COMBINE_AND, q4);
+ q6 = H5Qcreate(H5Q_TYPE_DATA_ELEM, H5Q_MATCH_EQUAL, H5T_NATIVE_INT, &value2);
+ q7 = H5Qcombine(q5, H5Q_COMBINE_OR, q6);
+
+ printf("Query is: ((17 < x < 22) && (x != 21.2)) || (x == 25)\n");
+
+ /* Apply queries */
+ ret = apply(q7);
+ if (ret == EXIT_SUCCESS) {
+ printf("------------------------------------------\n");
+ printf("Query apply tests passed on original query\n");
+ printf("------------------------------------------\n");
+ } else {
+ goto done;
+ }
+
+ H5Qencode(q7, NULL, &nalloc);
+ buf = (char *) malloc(nalloc);
+ H5Qencode(q7, buf, &nalloc);
+ q8 = H5Qdecode(buf);
+
+ /* Apply queries */
+ apply(q8);
+ if (ret == EXIT_SUCCESS) {
+ printf("------------------------------------------\n");
+ printf("Query apply tests passed on decoded query\n");
+ printf("------------------------------------------\n");
+ } else {
+ goto done;
+ }
+
+done:
+ free(buf);
+
+ H5Qclose(q8);
+ H5Qclose(q1);
+ H5Qclose(q2);
+ H5Qclose(q3);
+ H5Qclose(q4);
+ H5Qclose(q5);
+ H5Qclose(q6);
+ H5Qclose(q7);
+
+ return ret;
+}