summaryrefslogtreecommitdiffstats
path: root/src/H5Spoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Spoint.c')
-rw-r--r--src/H5Spoint.c181
1 files changed, 176 insertions, 5 deletions
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index 24dfe2a..cb7e98f 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -49,6 +49,8 @@ static htri_t H5S_point_is_contiguous(const H5S_t *space);
static htri_t H5S_point_is_single(const H5S_t *space);
static htri_t H5S_point_is_regular(const H5S_t *space);
static herr_t H5S_point_adjust_u(H5S_t *space, const hsize_t *offset);
+static herr_t H5S_point_project_scalar(const H5S_t *space, hsize_t *offset);
+static herr_t H5S_point_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
static herr_t H5S_point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space);
/* Selection iteration callbacks */
@@ -78,6 +80,8 @@ const H5S_select_class_t H5S_sel_point[1] = {{
H5S_point_is_single,
H5S_point_is_regular,
H5S_point_adjust_u,
+ H5S_point_project_scalar,
+ H5S_point_project_simple,
H5S_point_iter_init,
}};
@@ -610,18 +614,18 @@ H5S_point_copy(H5S_t *dst, const H5S_t *src, hbool_t UNUSED share_selection)
/* Allocate room for the head of the point list */
if(NULL == (dst->select.sel_info.pnt_lst = H5FL_MALLOC(H5S_pnt_list_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point list node")
curr = src->select.sel_info.pnt_lst->head;
new_tail = NULL;
while(curr) {
/* Create new point */
if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate point node")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node")
new_node->next = NULL;
- if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(src->extent.rank*sizeof(hsize_t)))) {
+ if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(src->extent.rank * sizeof(hsize_t)))) {
new_node = H5FL_FREE(H5S_pnt_node_t, new_node);
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate coordinate information")
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information")
} /* end if */
/* Copy over the point's coordinates */
@@ -976,7 +980,7 @@ H5S_get_select_elem_pointlist(H5S_t *space, hsize_t startpoint, hsize_t numpoint
node = node->next;
} /* end while */
- /* Iterate through the node, copying each hyperslab's information */
+ /* Iterate through the node, copying each point's information */
while(node != NULL && numpoints > 0) {
HDmemcpy(buf, node->pnt, sizeof(hsize_t) * rank);
buf += rank;
@@ -1346,6 +1350,173 @@ H5S_point_adjust_u(H5S_t *space, const hsize_t *offset)
} /* H5S_point_adjust_u() */
+/*-------------------------------------------------------------------------
+ * Function: H5S_point_project_scalar
+ *
+ * Purpose: Projects a single element point selection into a scalar
+ * dataspace
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_point_project_scalar(const H5S_t *space, hsize_t *offset)
+{
+ const H5S_pnt_node_t *node; /* Point node */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_point_project_scalar)
+
+ /* Check args */
+ HDassert(space && H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(space));
+ HDassert(offset);
+
+ /* Get the head of the point list */
+ node = space->select.sel_info.pnt_lst->head;
+
+ /* Check for more than one point selected */
+ if(node->next)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "point selection of one element has more than one node!")
+
+ /* Calculate offset of selection in projected buffer */
+ *offset = H5V_array_offset(space->extent.rank, space->extent.size, node->pnt);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_point_project_scalar() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_point_project_simple
+ *
+ * Purpose: Projects a point selection onto/into a simple dataspace
+ * of a different rank
+ *
+ * Return: non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *offset)
+{
+ const H5S_pnt_node_t *base_node; /* Point node in base space */
+ H5S_pnt_node_t *new_node; /* Point node in new space */
+ H5S_pnt_node_t *prev_node; /* Previous point node in new space */
+ unsigned rank_diff; /* Difference in ranks between spaces */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_point_project_simple)
+
+ /* Check args */
+ HDassert(base_space && H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(base_space));
+ HDassert(new_space);
+ HDassert(offset);
+
+ /* We are setting a new selection, remove any current selection in new dataspace */
+ if(H5S_SELECT_RELEASE(new_space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection")
+
+ /* Allocate room for the head of the point list */
+ if(NULL == (new_space->select.sel_info.pnt_lst = H5FL_MALLOC(H5S_pnt_list_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point list node")
+
+ /* Check if the new space's rank is < or > base space's rank */
+ if(new_space->extent.rank < base_space->extent.rank) {
+ hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */
+
+ /* Compute the difference in ranks */
+ rank_diff = base_space->extent.rank - new_space->extent.rank;
+
+ /* Calculate offset of selection in projected buffer */
+ HDmemset(block, 0, sizeof(block));
+ HDmemcpy(block, base_space->select.sel_info.pnt_lst->head->pnt, sizeof(hsize_t) * rank_diff);
+ *offset = H5V_array_offset(base_space->extent.rank, base_space->extent.size, block);
+
+ /* Iterate through base space's point nodes, copying the point information */
+ base_node = base_space->select.sel_info.pnt_lst->head;
+ prev_node = NULL;
+ while(base_node) {
+ /* Create new point */
+ if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node")
+ new_node->next = NULL;
+ if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(new_space->extent.rank * sizeof(hsize_t)))) {
+ new_node = H5FL_FREE(H5S_pnt_node_t, new_node);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information")
+ } /* end if */
+
+ /* Copy over the point's coordinates */
+ HDmemcpy(new_node->pnt, &base_node->pnt[rank_diff], (new_space->extent.rank * sizeof(hsize_t)));
+
+ /* Keep the order the same when copying */
+ if(NULL == prev_node)
+ prev_node = new_space->select.sel_info.pnt_lst->head = new_node;
+ else {
+ prev_node->next = new_node;
+ prev_node = new_node;
+ } /* end else */
+
+ /* Advance to next node */
+ base_node = base_node->next;
+ } /* end while */
+ } /* end if */
+ else {
+ HDassert(new_space->extent.rank > base_space->extent.rank);
+
+ /* Compute the difference in ranks */
+ rank_diff = new_space->extent.rank - base_space->extent.rank;
+
+ /* The offset is zero when projected into higher dimensions */
+ *offset = 0;
+
+ /* Iterate through base space's point nodes, copying the point information */
+ base_node = base_space->select.sel_info.pnt_lst->head;
+ prev_node = NULL;
+ while(base_node) {
+ /* Create new point */
+ if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node")
+ new_node->next = NULL;
+ if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(new_space->extent.rank * sizeof(hsize_t)))) {
+ new_node = H5FL_FREE(H5S_pnt_node_t, new_node);
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information")
+ } /* end if */
+
+ /* Copy over the point's coordinates */
+ HDmemset(new_node->pnt, 0, sizeof(hsize_t) * rank_diff);
+ HDmemcpy(&new_node->pnt[rank_diff], base_node->pnt, (new_space->extent.rank * sizeof(hsize_t)));
+
+ /* Keep the order the same when copying */
+ if(NULL == prev_node)
+ prev_node = new_space->select.sel_info.pnt_lst->head = new_node;
+ else {
+ prev_node->next = new_node;
+ prev_node = new_node;
+ } /* end else */
+
+ /* Advance to next node */
+ base_node = base_node->next;
+ } /* end while */
+ } /* end else */
+
+ /* Number of elements selected will be the same */
+ new_space->select.num_elem = base_space->select.num_elem;
+
+ /* Set selection type */
+ new_space->select.type = H5S_sel_point;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_point_project_simple() */
+
+
/*--------------------------------------------------------------------------
NAME
H5Sselect_elements