Coverage Report

Created: 2025-01-09 07:33

/src/hdf5/src/H5Sall.c
Line
Count
Source (jump to first uncovered line)
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*
14
 * Purpose: "All" selection dataspace I/O functions.
15
 */
16
17
/****************/
18
/* Module Setup */
19
/****************/
20
21
#include "H5Smodule.h" /* This source code file is part of the H5S module */
22
23
/***********/
24
/* Headers */
25
/***********/
26
#include "H5private.h"   /* Generic Functions                        */
27
#include "H5Eprivate.h"  /* Error handling                           */
28
#include "H5Iprivate.h"  /* ID Functions                             */
29
#include "H5Spkg.h"      /* Dataspace functions                      */
30
#include "H5VMprivate.h" /* Vector functions                         */
31
32
/****************/
33
/* Local Macros */
34
/****************/
35
36
/******************/
37
/* Local Typedefs */
38
/******************/
39
40
/********************/
41
/* Local Prototypes */
42
/********************/
43
44
/* Selection callbacks */
45
static herr_t   H5S__all_copy(H5S_t *dst, const H5S_t *src, bool share_selection);
46
static herr_t   H5S__all_release(H5S_t *space);
47
static htri_t   H5S__all_is_valid(const H5S_t *space);
48
static hssize_t H5S__all_serial_size(H5S_t *space);
49
static herr_t   H5S__all_serialize(H5S_t *space, uint8_t **p);
50
static herr_t   H5S__all_deserialize(H5S_t **space, const uint8_t **p, const size_t p_size, bool skip);
51
static herr_t   H5S__all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
52
static herr_t   H5S__all_offset(const H5S_t *space, hsize_t *off);
53
static int      H5S__all_unlim_dim(const H5S_t *space);
54
static htri_t   H5S__all_is_contiguous(const H5S_t *space);
55
static htri_t   H5S__all_is_single(const H5S_t *space);
56
static htri_t   H5S__all_is_regular(H5S_t *space);
57
static htri_t   H5S__all_shape_same(H5S_t *space1, H5S_t *space2);
58
static htri_t   H5S__all_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end);
59
static herr_t   H5S__all_adjust_u(H5S_t *space, const hsize_t *offset);
60
static herr_t   H5S__all_adjust_s(H5S_t *space, const hssize_t *offset);
61
static herr_t   H5S__all_project_scalar(const H5S_t *space, hsize_t *offset);
62
static herr_t   H5S__all_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset);
63
static herr_t   H5S__all_iter_init(H5S_t *space, H5S_sel_iter_t *iter);
64
65
/* Selection iteration callbacks */
66
static herr_t  H5S__all_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords);
67
static herr_t  H5S__all_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end);
68
static hsize_t H5S__all_iter_nelmts(const H5S_sel_iter_t *iter);
69
static htri_t  H5S__all_iter_has_next_block(const H5S_sel_iter_t *iter);
70
static herr_t  H5S__all_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
71
static herr_t  H5S__all_iter_next_block(H5S_sel_iter_t *sel_iter);
72
static herr_t  H5S__all_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes, size_t *nseq,
73
                                          size_t *nbytes, hsize_t *off, size_t *len);
74
static herr_t  H5S__all_iter_release(H5S_sel_iter_t *sel_iter);
75
76
/*****************************/
77
/* Library Private Variables */
78
/*****************************/
79
80
/*********************/
81
/* Package Variables */
82
/*********************/
83
84
/* Selection properties for "all" selections */
85
const H5S_select_class_t H5S_sel_all[1] = {{
86
    H5S_SEL_ALL,
87
88
    /* Methods on selection */
89
    H5S__all_copy,
90
    H5S__all_release,
91
    H5S__all_is_valid,
92
    H5S__all_serial_size,
93
    H5S__all_serialize,
94
    H5S__all_deserialize,
95
    H5S__all_bounds,
96
    H5S__all_offset,
97
    H5S__all_unlim_dim,
98
    NULL,
99
    H5S__all_is_contiguous,
100
    H5S__all_is_single,
101
    H5S__all_is_regular,
102
    H5S__all_shape_same,
103
    H5S__all_intersect_block,
104
    H5S__all_adjust_u,
105
    H5S__all_adjust_s,
106
    H5S__all_project_scalar,
107
    H5S__all_project_simple,
108
    H5S__all_iter_init,
109
}};
110
111
/*******************/
112
/* Local Variables */
113
/*******************/
114
115
/* Iteration properties for "all" selections */
116
static const H5S_sel_iter_class_t H5S_sel_iter_all[1] = {{
117
    H5S_SEL_ALL,
118
119
    /* Methods on selection iterator */
120
    H5S__all_iter_coords,
121
    H5S__all_iter_block,
122
    H5S__all_iter_nelmts,
123
    H5S__all_iter_has_next_block,
124
    H5S__all_iter_next,
125
    H5S__all_iter_next_block,
126
    H5S__all_iter_get_seq_list,
127
    H5S__all_iter_release,
128
}};
129
130
/*-------------------------------------------------------------------------
131
 * Function:  H5S__all_iter_init
132
 *
133
 * Purpose: Initializes iteration information for "all" selection.
134
 *
135
 * Return:  Non-negative on success, negative on failure.
136
 *
137
 *-------------------------------------------------------------------------
138
 */
139
static herr_t
140
H5S__all_iter_init(H5S_t H5_ATTR_UNUSED *space, H5S_sel_iter_t *iter)
141
0
{
142
0
    FUNC_ENTER_PACKAGE_NOERR
143
144
    /* Check args */
145
0
    assert(space && H5S_SEL_ALL == H5S_GET_SELECT_TYPE(space));
146
0
    assert(iter);
147
148
    /* Start at the upper left location */
149
0
    iter->u.all.elmt_offset = 0;
150
0
    iter->u.all.byte_offset = 0;
151
152
    /* Initialize type of selection iterator */
153
0
    iter->type = H5S_sel_iter_all;
154
155
0
    FUNC_LEAVE_NOAPI(SUCCEED)
156
0
} /* end H5S__all_iter_init() */
157
158
/*-------------------------------------------------------------------------
159
 * Function:  H5S__all_iter_coords
160
 *
161
 * Purpose: Retrieve the current coordinates of iterator for current
162
 *              selection
163
 *
164
 * Return:  Non-negative on success, negative on failure
165
 *
166
 *-------------------------------------------------------------------------
167
 */
168
static herr_t
169
H5S__all_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords)
170
0
{
171
0
    herr_t ret_value = SUCCEED; /* Return value */
172
173
0
    FUNC_ENTER_PACKAGE
174
175
    /* Check args */
176
0
    assert(iter);
177
0
    assert(coords);
178
179
    /* Calculate the coordinates for the current iterator offset */
180
0
    if (H5VM_array_calc(iter->u.all.elmt_offset, iter->rank, iter->dims, coords) < 0)
181
0
        HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve coordinates");
182
183
0
done:
184
0
    FUNC_LEAVE_NOAPI(ret_value)
185
0
} /* end H5S__all_iter_coords() */
186
187
/*-------------------------------------------------------------------------
188
 * Function:  H5S__all_iter_block
189
 *
190
 * Purpose: Retrieve the current block of iterator for current
191
 *              selection
192
 *
193
 * Return:  Non-negative on success, negative on failure
194
 *
195
 *-------------------------------------------------------------------------
196
 */
197
static herr_t
198
H5S__all_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
199
0
{
200
0
    unsigned u; /* Local index variable */
201
202
0
    FUNC_ENTER_PACKAGE_NOERR
203
204
    /* Check args */
205
0
    assert(iter);
206
0
    assert(start);
207
0
    assert(end);
208
209
0
    for (u = 0; u < iter->rank; u++) {
210
        /* Set the start of the 'all' block */
211
        /* (Always '0' coordinates for now) */
212
0
        start[u] = 0;
213
214
        /* Compute the end of the 'all' block */
215
        /* (Always size of the extent for now) */
216
0
        end[u] = iter->dims[u] - 1;
217
0
    } /* end for */
218
219
0
    FUNC_LEAVE_NOAPI(SUCCEED)
220
0
} /* end H5S__all_iter_block() */
221
222
/*-------------------------------------------------------------------------
223
 * Function:  H5S__all_iter_nelmts
224
 *
225
 * Purpose: Return number of elements left to process in iterator
226
 *
227
 * Return:  Non-negative number of elements on success, zero on failure
228
 *
229
 *-------------------------------------------------------------------------
230
 */
231
static hsize_t
232
H5S__all_iter_nelmts(const H5S_sel_iter_t *iter)
233
0
{
234
0
    FUNC_ENTER_PACKAGE_NOERR
235
236
    /* Check args */
237
0
    assert(iter);
238
239
0
    FUNC_LEAVE_NOAPI(iter->elmt_left)
240
0
} /* end H5S__all_iter_nelmts() */
241
242
/*--------------------------------------------------------------------------
243
 NAME
244
    H5S__all_iter_has_next_block
245
 PURPOSE
246
    Check if there is another block left in the current iterator
247
 USAGE
248
    htri_t H5S__all_iter_has_next_block(iter)
249
        const H5S_sel_iter_t *iter;       IN: Pointer to selection iterator
250
 RETURNS
251
    Non-negative (true/false) on success/Negative on failure
252
 DESCRIPTION
253
    Check if there is another block available in the selection iterator.
254
 GLOBAL VARIABLES
255
 COMMENTS, BUGS, ASSUMPTIONS
256
 EXAMPLES
257
 REVISION LOG
258
--------------------------------------------------------------------------*/
259
static htri_t
260
H5S__all_iter_has_next_block(const H5S_sel_iter_t H5_ATTR_UNUSED *iter)
261
0
{
262
0
    FUNC_ENTER_PACKAGE_NOERR
263
264
    /* Check args */
265
0
    assert(iter);
266
267
0
    FUNC_LEAVE_NOAPI(false)
268
0
} /* end H5S__all_iter_has_next_block() */
269
270
/*--------------------------------------------------------------------------
271
 NAME
272
    H5S__all_iter_next
273
 PURPOSE
274
    Increment selection iterator
275
 USAGE
276
    herr_t H5S__all_iter_next(iter, nelem)
277
        H5S_sel_iter_t *iter;       IN: Pointer to selection iterator
278
        size_t nelem;               IN: Number of elements to advance by
279
 RETURNS
280
    Non-negative on success/Negative on failure
281
 DESCRIPTION
282
    Advance selection iterator to the NELEM'th next element in the selection.
283
 GLOBAL VARIABLES
284
 COMMENTS, BUGS, ASSUMPTIONS
285
 EXAMPLES
286
 REVISION LOG
287
--------------------------------------------------------------------------*/
288
static herr_t
289
H5S__all_iter_next(H5S_sel_iter_t *iter, size_t nelem)
290
0
{
291
0
    FUNC_ENTER_PACKAGE_NOERR
292
293
    /* Check args */
294
0
    assert(iter);
295
0
    assert(nelem > 0);
296
297
    /* Increment the iterator */
298
0
    iter->u.all.elmt_offset += nelem;
299
0
    iter->u.all.byte_offset += (nelem * iter->elmt_size);
300
301
0
    FUNC_LEAVE_NOAPI(SUCCEED)
302
0
} /* end H5S__all_iter_next() */
303
304
/*--------------------------------------------------------------------------
305
 NAME
306
    H5S__all_iter_next_block
307
 PURPOSE
308
    Increment selection iterator to next block
309
 USAGE
310
    herr_t H5S__all_iter_next_block(iter)
311
        H5S_sel_iter_t *iter;       IN: Pointer to selection iterator
312
 RETURNS
313
    Non-negative on success/Negative on failure
314
 DESCRIPTION
315
    Advance selection iterator to the next block in the selection.
316
 GLOBAL VARIABLES
317
 COMMENTS, BUGS, ASSUMPTIONS
318
 EXAMPLES
319
 REVISION LOG
320
--------------------------------------------------------------------------*/
321
static herr_t
322
H5S__all_iter_next_block(H5S_sel_iter_t H5_ATTR_UNUSED *iter)
323
0
{
324
0
    FUNC_ENTER_PACKAGE_NOERR
325
326
    /* Check args */
327
0
    assert(iter);
328
329
0
    FUNC_LEAVE_NOAPI(FAIL)
330
0
} /* end H5S__all_iter_next_block() */
331
332
/*--------------------------------------------------------------------------
333
 NAME
334
    H5S__all_iter_get_seq_list
335
 PURPOSE
336
    Create a list of offsets & lengths for a selection
337
 USAGE
338
    herr_t H5S__all_iter_get_seq_list(iter,maxseq,maxelem,nseq,nelem,off,len)
339
        H5S_sel_iter_t *iter;   IN/OUT: Selection iterator describing last
340
                                    position of interest in selection.
341
        size_t maxseq;          IN: Maximum number of sequences to generate
342
        size_t maxelem;         IN: Maximum number of elements to include in the
343
                                    generated sequences
344
        size_t *nseq;           OUT: Actual number of sequences generated
345
        size_t *nelem;          OUT: Actual number of elements in sequences generated
346
        hsize_t *off;           OUT: Array of offsets
347
        size_t *len;            OUT: Array of lengths
348
 RETURNS
349
    Non-negative on success/Negative on failure.
350
 DESCRIPTION
351
    Use the selection in the dataspace to generate a list of byte offsets and
352
    lengths for the region(s) selected.  Start/Restart from the position in the
353
    ITER parameter.  The number of sequences generated is limited by the MAXSEQ
354
    parameter and the number of sequences actually generated is stored in the
355
    NSEQ parameter.
356
 GLOBAL VARIABLES
357
 COMMENTS, BUGS, ASSUMPTIONS
358
 EXAMPLES
359
 REVISION LOG
360
--------------------------------------------------------------------------*/
361
static herr_t
362
H5S__all_iter_get_seq_list(H5S_sel_iter_t *iter, size_t H5_ATTR_UNUSED maxseq, size_t maxelem, size_t *nseq,
363
                           size_t *nelem, hsize_t *off, size_t *len)
364
0
{
365
0
    size_t elem_used; /* The number of elements used */
366
367
0
    FUNC_ENTER_PACKAGE_NOERR
368
369
    /* Check args */
370
0
    assert(iter);
371
0
    assert(maxseq > 0);
372
0
    assert(maxelem > 0);
373
0
    assert(nseq);
374
0
    assert(nelem);
375
0
    assert(off);
376
0
    assert(len);
377
378
    /* Determine the actual number of elements to use */
379
0
    H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t);
380
0
    elem_used = MIN(maxelem, (size_t)iter->elmt_left);
381
0
    assert(elem_used > 0);
382
383
    /* Compute the offset in the dataset */
384
0
    off[0] = iter->u.all.byte_offset;
385
0
    len[0] = elem_used * iter->elmt_size;
386
387
    /* Should only need one sequence for 'all' selections */
388
0
    *nseq = 1;
389
390
    /* Set the number of elements used */
391
0
    *nelem = elem_used;
392
393
    /* Update the iterator */
394
0
    iter->elmt_left -= elem_used;
395
0
    iter->u.all.elmt_offset += elem_used;
396
0
    iter->u.all.byte_offset += len[0];
397
398
0
    FUNC_LEAVE_NOAPI(SUCCEED)
399
0
} /* end H5S__all_iter_get_seq_list() */
400
401
/*--------------------------------------------------------------------------
402
 NAME
403
    H5S__all_iter_release
404
 PURPOSE
405
    Release "all" selection iterator information for a dataspace
406
 USAGE
407
    herr_t H5S__all_iter_release(iter)
408
        H5S_sel_iter_t *iter;       IN: Pointer to selection iterator
409
 RETURNS
410
    Non-negative on success/Negative on failure
411
 DESCRIPTION
412
    Releases all information for a dataspace "all" selection iterator
413
 GLOBAL VARIABLES
414
 COMMENTS, BUGS, ASSUMPTIONS
415
 EXAMPLES
416
 REVISION LOG
417
--------------------------------------------------------------------------*/
418
static herr_t
419
H5S__all_iter_release(H5S_sel_iter_t H5_ATTR_UNUSED *iter)
420
0
{
421
0
    FUNC_ENTER_PACKAGE_NOERR
422
423
    /* Check args */
424
0
    assert(iter);
425
426
0
    FUNC_LEAVE_NOAPI(SUCCEED)
427
0
} /* end H5S__all_iter_release() */
428
429
/*--------------------------------------------------------------------------
430
 NAME
431
    H5S__all_release
432
 PURPOSE
433
    Release all selection information for a dataspace
434
 USAGE
435
    herr_t H5S__all_release(space)
436
        H5S_t *space;       IN: Pointer to dataspace
437
 RETURNS
438
    Non-negative on success/Negative on failure
439
 DESCRIPTION
440
    Releases "all" selection information for a dataspace
441
 GLOBAL VARIABLES
442
 COMMENTS, BUGS, ASSUMPTIONS
443
 EXAMPLES
444
 REVISION LOG
445
--------------------------------------------------------------------------*/
446
static herr_t
447
H5S__all_release(H5S_t *space)
448
0
{
449
0
    FUNC_ENTER_PACKAGE_NOERR
450
451
    /* Check args */
452
0
    assert(space);
453
454
    /* Reset the number of elements in the selection */
455
0
    space->select.num_elem = 0;
456
457
0
    FUNC_LEAVE_NOAPI(SUCCEED)
458
0
} /* end H5S__all_release() */
459
460
/*--------------------------------------------------------------------------
461
 NAME
462
    H5S__all_copy
463
 PURPOSE
464
    Copy a selection from one dataspace to another
465
 USAGE
466
    herr_t H5S__all_copy(dst, src, share_selection)
467
        H5S_t *dst;  OUT: Pointer to the destination dataspace
468
        H5S_t *src;  IN: Pointer to the source dataspace
469
        bool;     IN: Whether to share the selection between the dataspaces
470
 RETURNS
471
    Non-negative on success/Negative on failure
472
 DESCRIPTION
473
    Copies the 'all' selection information from the source
474
    dataspace to the destination dataspace.
475
 GLOBAL VARIABLES
476
 COMMENTS, BUGS, ASSUMPTIONS
477
 EXAMPLES
478
 REVISION LOG
479
--------------------------------------------------------------------------*/
480
static herr_t
481
H5S__all_copy(H5S_t *dst, const H5S_t H5_ATTR_UNUSED *src, bool H5_ATTR_UNUSED share_selection)
482
0
{
483
0
    FUNC_ENTER_PACKAGE_NOERR
484
485
0
    assert(src);
486
0
    assert(dst);
487
488
    /* Set number of elements in selection */
489
0
    dst->select.num_elem = (hsize_t)H5S_GET_EXTENT_NPOINTS(dst);
490
491
0
    FUNC_LEAVE_NOAPI(SUCCEED)
492
0
} /* end H5S__all_copy() */
493
494
/*--------------------------------------------------------------------------
495
 NAME
496
    H5S__all_is_valid
497
 PURPOSE
498
    Check whether the selection fits within the extent, with the current
499
    offset defined.
500
 USAGE
501
    htri_t H5S__all_is_valid(space);
502
        H5S_t *space;             IN: Dataspace pointer to query
503
 RETURNS
504
    true if the selection fits within the extent, false if it does not and
505
        Negative on an error.
506
 DESCRIPTION
507
    Determines if the current selection at the current offset fits within the
508
    extent for the dataspace.  Offset is irrelevant for this type of selection.
509
 GLOBAL VARIABLES
510
 COMMENTS, BUGS, ASSUMPTIONS
511
 EXAMPLES
512
 REVISION LOG
513
--------------------------------------------------------------------------*/
514
static htri_t
515
H5S__all_is_valid(const H5S_t H5_ATTR_UNUSED *space)
516
0
{
517
0
    FUNC_ENTER_PACKAGE_NOERR
518
519
0
    assert(space);
520
521
0
    FUNC_LEAVE_NOAPI(true)
522
0
} /* end H5S__all_is_valid() */
523
524
/*--------------------------------------------------------------------------
525
 NAME
526
    H5S__all_serial_size
527
 PURPOSE
528
    Determine the number of bytes needed to store the serialized "all"
529
        selection information.
530
 USAGE
531
    hssize_t H5S__all_serial_size(space)
532
        H5S_t *space;             IN: Dataspace pointer to query
533
 RETURNS
534
    The number of bytes required on success, negative on an error.
535
 DESCRIPTION
536
    Determines the number of bytes required to serialize an "all"
537
    selection for storage on disk.
538
 GLOBAL VARIABLES
539
 COMMENTS, BUGS, ASSUMPTIONS
540
 EXAMPLES
541
 REVISION LOG
542
--------------------------------------------------------------------------*/
543
static hssize_t
544
H5S__all_serial_size(H5S_t H5_ATTR_UNUSED *space)
545
0
{
546
0
    FUNC_ENTER_PACKAGE_NOERR
547
548
0
    assert(space);
549
550
    /* Basic number of bytes required to serialize point selection:
551
     *  <type (4 bytes)> + <version (4 bytes)> + <padding (4 bytes)> +
552
     *      <length (4 bytes)> = 16 bytes
553
     */
554
0
    FUNC_LEAVE_NOAPI(16)
555
0
} /* end H5S__all_serial_size() */
556
557
/*--------------------------------------------------------------------------
558
 NAME
559
    H5S__all_serialize
560
 PURPOSE
561
    Serialize the current selection into a user-provided buffer.
562
 USAGE
563
    herr_t H5S__all_serialize(space, p)
564
        H5S_t *space;           IN: Dataspace with selection to serialize
565
        uint8_t **p;            OUT: Pointer to buffer to put serialized
566
                                selection.  Will be advanced to end of
567
                                serialized selection.
568
 RETURNS
569
    Non-negative on success/Negative on failure
570
 DESCRIPTION
571
    Serializes the current element selection into a buffer.  (Primarily for
572
    storing on disk).
573
 GLOBAL VARIABLES
574
 COMMENTS, BUGS, ASSUMPTIONS
575
 EXAMPLES
576
 REVISION LOG
577
--------------------------------------------------------------------------*/
578
static herr_t
579
H5S__all_serialize(H5S_t *space, uint8_t **p)
580
0
{
581
0
    uint8_t *pp = (*p); /* Local pointer for decoding */
582
583
0
    FUNC_ENTER_PACKAGE_NOERR
584
585
    /* Check args */
586
0
    assert(space);
587
0
    assert(p);
588
0
    assert(pp);
589
590
    /* Store the preamble information */
591
0
    UINT32ENCODE(pp, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
592
0
    UINT32ENCODE(pp, (uint32_t)H5S_ALL_VERSION_1);          /* Store the version number */
593
0
    UINT32ENCODE(pp, (uint32_t)0);                          /* Store the un-used padding */
594
0
    UINT32ENCODE(pp, (uint32_t)0);                          /* Store the additional information length */
595
596
    /* Update encoding pointer */
597
0
    *p = pp;
598
599
0
    FUNC_LEAVE_NOAPI(SUCCEED)
600
0
} /* end H5S__all_serialize() */
601
602
/*--------------------------------------------------------------------------
603
 NAME
604
    H5S__all_deserialize
605
 PURPOSE
606
    Deserialize the current selection from a user-provided buffer.
607
 USAGE
608
    herr_t H5S_all_deserialize(space, p)
609
        H5S_t **space;          IN/OUT: Dataspace pointer to place
610
                                selection into
611
        uint8 **p;              OUT: Pointer to buffer holding serialized
612
                                selection.  Will be advanced to end of
613
                                serialized selection.
614
 RETURNS
615
    Non-negative on success/Negative on failure
616
 DESCRIPTION
617
    Deserializes the current selection into a buffer.  (Primarily for retrieving
618
    from disk).
619
 GLOBAL VARIABLES
620
 COMMENTS, BUGS, ASSUMPTIONS
621
 EXAMPLES
622
 REVISION LOG
623
--------------------------------------------------------------------------*/
624
static herr_t
625
H5S__all_deserialize(H5S_t **space, const uint8_t **p, const size_t p_size, bool skip)
626
0
{
627
0
    uint32_t version;                           /* Version number */
628
0
    H5S_t   *tmp_space = NULL;                  /* Pointer to actual dataspace to use,
629
                                                   either *space or a newly allocated one */
630
0
    herr_t         ret_value = SUCCEED;         /* return value */
631
0
    const uint8_t *p_end     = *p + p_size - 1; /* Pointer to last valid byte in buffer */
632
0
    FUNC_ENTER_PACKAGE
633
634
0
    assert(p);
635
0
    assert(*p);
636
637
    /* As part of the efforts to push all selection-type specific coding
638
       to the callbacks, the coding for the allocation of a null dataspace
639
       is moved from H5S_select_deserialize() in H5Sselect.c.
640
       This is needed for decoding virtual layout in H5O__layout_decode() */
641
642
    /* Allocate space if not provided */
643
0
    if (!*space) {
644
0
        if (NULL == (tmp_space = H5S_create(H5S_SIMPLE)))
645
0
            HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace");
646
0
    } /* end if */
647
0
    else
648
0
        tmp_space = *space;
649
650
    /* Decode version */
651
0
    if (H5_IS_KNOWN_BUFFER_OVERFLOW(skip, *p, sizeof(uint32_t), p_end))
652
0
        HGOTO_ERROR(H5E_DATASPACE, H5E_OVERFLOW, FAIL, "buffer overflow while decoding selection version");
653
0
    UINT32DECODE(*p, version);
654
655
0
    if (version < H5S_ALL_VERSION_1 || version > H5S_ALL_VERSION_LATEST)
656
0
        HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "bad version number for all selection");
657
658
    /* Skip over the remainder of the header */
659
0
    if (H5_IS_KNOWN_BUFFER_OVERFLOW(skip, *p, 8, p_end))
660
0
        HGOTO_ERROR(H5E_DATASPACE, H5E_OVERFLOW, FAIL, "buffer overflow while decoding header");
661
0
    *p += 8;
662
663
    /* Change to "all" selection */
664
0
    if (H5S_select_all(tmp_space, true) < 0)
665
0
        HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection");
666
667
    /* Return space to the caller if allocated */
668
0
    if (!*space)
669
0
        *space = tmp_space;
670
671
0
done:
672
    /* Free temporary space if not passed to caller (only happens on error) */
673
0
    if (!*space && tmp_space)
674
0
        if (H5S_close(tmp_space) < 0)
675
0
            HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace");
676
677
0
    FUNC_LEAVE_NOAPI(ret_value)
678
0
} /* end H5S__all_deserialize() */
679
680
/*--------------------------------------------------------------------------
681
 NAME
682
    H5S__all_bounds
683
 PURPOSE
684
    Gets the bounding box containing the selection.
685
 USAGE
686
    herr_t H5S__all_bounds(space, start, end)
687
        H5S_t *space;           IN: Dataspace pointer of selection to query
688
        hsize_t *start;         OUT: Starting coordinate of bounding box
689
        hsize_t *end;           OUT: Opposite coordinate of bounding box
690
 RETURNS
691
    Non-negative on success, negative on failure
692
 DESCRIPTION
693
    Retrieves the bounding box containing the current selection and places
694
    it into the user's buffers.  The start and end buffers must be large
695
    enough to hold the dataspace rank number of coordinates.  The bounding box
696
    exactly contains the selection, ie. if a 2-D element selection is currently
697
    defined with the following points: (4,5), (6,8) (10,7), the bounding box
698
    with be (4, 5), (10, 8).  Calling this function on a "none" selection
699
    returns fail.
700
 GLOBAL VARIABLES
701
 COMMENTS, BUGS, ASSUMPTIONS
702
 EXAMPLES
703
 REVISION LOG
704
--------------------------------------------------------------------------*/
705
static herr_t
706
H5S__all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
707
0
{
708
0
    unsigned rank; /* Dataspace rank */
709
0
    unsigned i;    /* index variable */
710
711
0
    FUNC_ENTER_PACKAGE_NOERR
712
713
0
    assert(space);
714
0
    assert(start);
715
0
    assert(end);
716
717
    /* Get the dataspace extent rank */
718
0
    rank = space->extent.rank;
719
720
    /* Just copy over the complete extent */
721
0
    for (i = 0; i < rank; i++) {
722
0
        start[i] = 0;
723
0
        end[i]   = space->extent.size[i] - 1;
724
0
    } /* end for */
725
726
0
    FUNC_LEAVE_NOAPI(SUCCEED)
727
0
} /* end H5S__all_bounds() */
728
729
/*--------------------------------------------------------------------------
730
 NAME
731
    H5S__all_offset
732
 PURPOSE
733
    Gets the linear offset of the first element for the selection.
734
 USAGE
735
    herr_t H5S__all_offset(space, offset)
736
        const H5S_t *space;     IN: Dataspace pointer of selection to query
737
        hsize_t *offset;        OUT: Linear offset of first element in selection
738
 RETURNS
739
    Non-negative on success, negative on failure
740
 DESCRIPTION
741
    Retrieves the linear offset (in "units" of elements) of the first element
742
    selected within the dataspace.
743
 GLOBAL VARIABLES
744
 COMMENTS, BUGS, ASSUMPTIONS
745
    Calling this function on a "none" selection returns fail.
746
 EXAMPLES
747
 REVISION LOG
748
--------------------------------------------------------------------------*/
749
static herr_t
750
H5S__all_offset(const H5S_t H5_ATTR_UNUSED *space, hsize_t *offset)
751
0
{
752
0
    FUNC_ENTER_PACKAGE_NOERR
753
754
0
    assert(space);
755
0
    assert(offset);
756
757
    /* 'All' selections always start at offset 0 */
758
0
    *offset = 0;
759
760
0
    FUNC_LEAVE_NOAPI(SUCCEED)
761
0
} /* end H5S__all_offset() */
762
763
/*--------------------------------------------------------------------------
764
 NAME
765
    H5S__all_unlim_dim
766
 PURPOSE
767
    Return unlimited dimension of selection, or -1 if none
768
 USAGE
769
    int H5S__all_unlim_dim(space)
770
        H5S_t *space;           IN: Dataspace pointer to check
771
 RETURNS
772
    Unlimited dimension of selection, or -1 if none (never fails).
773
 DESCRIPTION
774
    Returns the index of the unlimited dimension in this selection, or -1
775
    if the selection has no unlimited dimension.  "All" selections are
776
    always unlimited in every dimension, though this is not reflected in
777
    other calls, where the selection is "clipped" against the current
778
    extent, so for consistency this function always returns -1.
779
 GLOBAL VARIABLES
780
 COMMENTS, BUGS, ASSUMPTIONS
781
 EXAMPLES
782
 REVISION LOG
783
--------------------------------------------------------------------------*/
784
static int
785
H5S__all_unlim_dim(const H5S_t H5_ATTR_UNUSED *space)
786
0
{
787
0
    FUNC_ENTER_PACKAGE_NOERR
788
789
0
    FUNC_LEAVE_NOAPI(-1)
790
0
} /* end H5S__all_unlim_dim() */
791
792
/*--------------------------------------------------------------------------
793
 NAME
794
    H5S__all_is_contiguous
795
 PURPOSE
796
    Check if a "all" selection is contiguous within the dataspace extent.
797
 USAGE
798
    htri_t H5S__all_is_contiguous(space)
799
        H5S_t *space;           IN: Dataspace pointer to check
800
 RETURNS
801
    true/false/FAIL
802
 DESCRIPTION
803
    Checks to see if the current selection in the dataspace is contiguous.
804
    This is primarily used for reading the entire selection in one swoop.
805
 GLOBAL VARIABLES
806
 COMMENTS, BUGS, ASSUMPTIONS
807
 EXAMPLES
808
 REVISION LOG
809
--------------------------------------------------------------------------*/
810
static htri_t
811
H5S__all_is_contiguous(const H5S_t H5_ATTR_UNUSED *space)
812
0
{
813
0
    FUNC_ENTER_PACKAGE_NOERR
814
815
0
    assert(space);
816
817
0
    FUNC_LEAVE_NOAPI(true)
818
0
} /* end H5S__all_is_contiguous() */
819
820
/*--------------------------------------------------------------------------
821
 NAME
822
    H5S__all_is_single
823
 PURPOSE
824
    Check if a "all" selection is a single block within the dataspace extent.
825
 USAGE
826
    htri_t H5S__all_is_single(space)
827
        H5S_t *space;           IN: Dataspace pointer to check
828
 RETURNS
829
    true/false/FAIL
830
 DESCRIPTION
831
    Checks to see if the current selection in the dataspace is a single block.
832
    This is primarily used for reading the entire selection in one swoop.
833
 GLOBAL VARIABLES
834
 COMMENTS, BUGS, ASSUMPTIONS
835
 EXAMPLES
836
 REVISION LOG
837
--------------------------------------------------------------------------*/
838
static htri_t
839
H5S__all_is_single(const H5S_t H5_ATTR_UNUSED *space)
840
0
{
841
0
    FUNC_ENTER_PACKAGE_NOERR
842
843
0
    assert(space);
844
845
0
    FUNC_LEAVE_NOAPI(true)
846
0
} /* end H5S__all_is_single() */
847
848
/*--------------------------------------------------------------------------
849
 NAME
850
    H5S__all_is_regular
851
 PURPOSE
852
    Check if a "all" selection is "regular"
853
 USAGE
854
    htri_t H5S__all_is_regular(space)
855
        H5S_t *space;     IN: Dataspace pointer to check
856
 RETURNS
857
    true/false/FAIL
858
 DESCRIPTION
859
    Checks to see if the current selection in a dataspace is the a regular
860
    pattern.
861
    This is primarily used for reading the entire selection in one swoop.
862
 GLOBAL VARIABLES
863
 COMMENTS, BUGS, ASSUMPTIONS
864
 EXAMPLES
865
 REVISION LOG
866
--------------------------------------------------------------------------*/
867
static htri_t
868
H5S__all_is_regular(H5S_t H5_ATTR_UNUSED *space)
869
0
{
870
0
    FUNC_ENTER_PACKAGE_NOERR
871
872
    /* Check args */
873
0
    assert(space);
874
875
0
    FUNC_LEAVE_NOAPI(true)
876
0
} /* end H5S__all_is_regular() */
877
878
/*--------------------------------------------------------------------------
879
 NAME
880
    H5S__all_shape_same
881
 PURPOSE
882
    Check if a two "all" selections are the same shape
883
 USAGE
884
    htri_t H5S__all_shape_same(space1, space2)
885
        H5S_t *space1;           IN: First dataspace to check
886
        H5S_t *space2;           IN: Second dataspace to check
887
 RETURNS
888
    true / false / FAIL
889
 DESCRIPTION
890
    Checks to see if the current selection in each dataspace are the same
891
    shape.
892
 GLOBAL VARIABLES
893
 COMMENTS, BUGS, ASSUMPTIONS
894
 EXAMPLES
895
 REVISION LOG
896
--------------------------------------------------------------------------*/
897
static htri_t
898
H5S__all_shape_same(H5S_t *space1, H5S_t *space2)
899
0
{
900
0
    int    space1_dim;       /* Current dimension in first dataspace */
901
0
    int    space2_dim;       /* Current dimension in second dataspace */
902
0
    htri_t ret_value = true; /* Return value */
903
904
0
    FUNC_ENTER_PACKAGE_NOERR
905
906
    /* Check args */
907
0
    assert(space1);
908
0
    assert(space2);
909
910
    /* Initialize dataspace dims */
911
0
    space1_dim = (int)space1->extent.rank - 1;
912
0
    space2_dim = (int)space2->extent.rank - 1;
913
914
    /* Recall that space1_rank >= space2_rank.
915
     *
916
     * In the following while loop, we test to see if space1 and space2
917
     * have identical size in all dimensions they have in common.
918
     */
919
0
    while (space2_dim >= 0) {
920
0
        if (space1->extent.size[space1_dim] != space2->extent.size[space2_dim])
921
0
            HGOTO_DONE(false);
922
923
0
        space1_dim--;
924
0
        space2_dim--;
925
0
    } /* end while */
926
927
    /* Since we are selecting the entire space, we must also verify that space1
928
     * has size 1 in all dimensions that it does not share with space2.
929
     */
930
0
    while (space1_dim >= 0) {
931
0
        if (space1->extent.size[space1_dim] != 1)
932
0
            HGOTO_DONE(false);
933
934
0
        space1_dim--;
935
0
    } /* end while */
936
937
0
done:
938
0
    FUNC_LEAVE_NOAPI(ret_value)
939
0
} /* end H5S__all_shape_same() */
940
941
/*--------------------------------------------------------------------------
942
 NAME
943
    H5S__all_intersect_block
944
 PURPOSE
945
    Detect intersections of selection with block
946
 USAGE
947
    htri_t H5S__all_intersect_block(space, start, end)
948
        H5S_t *space;           IN: Dataspace with selection to use
949
        const hsize_t *start;   IN: Starting coordinate for block
950
        const hsize_t *end;     IN: Ending coordinate for block
951
 RETURNS
952
    Non-negative true / false on success, negative on failure
953
 DESCRIPTION
954
    Quickly detect intersections with a block
955
 GLOBAL VARIABLES
956
 COMMENTS, BUGS, ASSUMPTIONS
957
 EXAMPLES
958
 REVISION LOG
959
--------------------------------------------------------------------------*/
960
htri_t
961
H5S__all_intersect_block(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *start,
962
                         const hsize_t H5_ATTR_UNUSED *end)
963
0
{
964
0
    FUNC_ENTER_PACKAGE_NOERR
965
966
    /* Sanity check */
967
0
    assert(space);
968
0
    assert(H5S_SEL_ALL == H5S_GET_SELECT_TYPE(space));
969
0
    assert(start);
970
0
    assert(end);
971
972
0
    FUNC_LEAVE_NOAPI(true)
973
0
} /* end H5S__all_intersect_block() */
974
975
/*--------------------------------------------------------------------------
976
 NAME
977
    H5S__all_adjust_u
978
 PURPOSE
979
    Adjust an "all" selection by subtracting an offset
980
 USAGE
981
    herr_t H5S__all_adjust_u(space, offset)
982
        H5S_t *space;           IN/OUT: Pointer to dataspace to adjust
983
        const hsize_t *offset; IN: Offset to subtract
984
 RETURNS
985
    Non-negative on success, negative on failure
986
 DESCRIPTION
987
    Moves selection by subtracting an offset from it.
988
 GLOBAL VARIABLES
989
 COMMENTS, BUGS, ASSUMPTIONS
990
 EXAMPLES
991
 REVISION LOG
992
--------------------------------------------------------------------------*/
993
static herr_t
994
H5S__all_adjust_u(H5S_t H5_ATTR_UNUSED *space, const hsize_t H5_ATTR_UNUSED *offset)
995
0
{
996
0
    FUNC_ENTER_PACKAGE_NOERR
997
998
    /* Check args */
999
0
    assert(space);
1000
0
    assert(offset);
1001
1002
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1003
0
} /* end H5S__all_adjust_u() */
1004
1005
/*--------------------------------------------------------------------------
1006
 NAME
1007
    H5S__all_adjust_s
1008
 PURPOSE
1009
    Adjust an "all" selection by subtracting an offset
1010
 USAGE
1011
    herr_t H5S__all_adjust_u(space, offset)
1012
        H5S_t *space;           IN/OUT: Pointer to dataspace to adjust
1013
        const hssize_t *offset; IN: Offset to subtract
1014
 RETURNS
1015
    Non-negative on success, negative on failure
1016
 DESCRIPTION
1017
    Moves selection by subtracting an offset from it.
1018
 GLOBAL VARIABLES
1019
 COMMENTS, BUGS, ASSUMPTIONS
1020
 EXAMPLES
1021
 REVISION LOG
1022
--------------------------------------------------------------------------*/
1023
static herr_t
1024
H5S__all_adjust_s(H5S_t H5_ATTR_UNUSED *space, const hssize_t H5_ATTR_UNUSED *offset)
1025
0
{
1026
0
    FUNC_ENTER_PACKAGE_NOERR
1027
1028
    /* Check args */
1029
0
    assert(space);
1030
0
    assert(offset);
1031
1032
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1033
0
} /* end H5S__all_adjust_s() */
1034
1035
/*-------------------------------------------------------------------------
1036
 * Function:  H5S__all_project_scalar
1037
 *
1038
 * Purpose: Projects a single element 'all' selection into a scalar
1039
 *              dataspace
1040
 *
1041
 * Return:  Non-negative on success, negative on failure.
1042
 *
1043
 *-------------------------------------------------------------------------
1044
 */
1045
static herr_t
1046
H5S__all_project_scalar(const H5S_t H5_ATTR_UNUSED *space, hsize_t *offset)
1047
0
{
1048
0
    FUNC_ENTER_PACKAGE_NOERR
1049
1050
    /* Check args */
1051
0
    assert(space && H5S_SEL_ALL == H5S_GET_SELECT_TYPE(space));
1052
0
    assert(offset);
1053
1054
    /* Set offset of selection in projected buffer */
1055
0
    *offset = 0;
1056
1057
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1058
0
} /* end H5S__all_project_scalar() */
1059
1060
/*-------------------------------------------------------------------------
1061
 * Function:  H5S__all_project_simple
1062
 *
1063
 * Purpose: Projects an 'all' selection onto/into a simple dataspace
1064
 *              of a different rank
1065
 *
1066
 * Return:  Non-negative on success, negative on failure.
1067
 *
1068
 *-------------------------------------------------------------------------
1069
 */
1070
static herr_t
1071
H5S__all_project_simple(const H5S_t H5_ATTR_UNUSED *base_space, H5S_t *new_space,
1072
                        hsize_t H5_ATTR_UNUSED *offset)
1073
0
{
1074
0
    herr_t ret_value = SUCCEED; /* Return value */
1075
1076
0
    FUNC_ENTER_PACKAGE
1077
1078
    /* Check args */
1079
0
    assert(base_space && H5S_SEL_ALL == H5S_GET_SELECT_TYPE(base_space));
1080
0
    assert(new_space);
1081
0
    assert(offset);
1082
1083
    /* Select the entire new space */
1084
0
    if (H5S_select_all(new_space, true) < 0)
1085
0
        HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to set all selection");
1086
1087
0
done:
1088
0
    FUNC_LEAVE_NOAPI(ret_value)
1089
0
} /* end H5S__all_project_simple() */
1090
1091
/*--------------------------------------------------------------------------
1092
 NAME
1093
    H5S_select_all
1094
 PURPOSE
1095
    Specify the entire extent is selected
1096
 USAGE
1097
    herr_t H5S_select_all(dsid)
1098
        hid_t dsid;             IN: Dataspace ID of selection to modify
1099
        bool rel_prev;      IN: Flag whether to release previous selection or not
1100
 RETURNS
1101
    Non-negative on success/Negative on failure
1102
 DESCRIPTION
1103
    This function selects the entire extent for a dataspace.
1104
 GLOBAL VARIABLES
1105
 COMMENTS, BUGS, ASSUMPTIONS
1106
 EXAMPLES
1107
 REVISION LOG
1108
--------------------------------------------------------------------------*/
1109
herr_t
1110
H5S_select_all(H5S_t *space, bool rel_prev)
1111
0
{
1112
0
    herr_t ret_value = SUCCEED; /* return value */
1113
1114
0
    FUNC_ENTER_NOAPI(FAIL)
1115
1116
    /* Check args */
1117
0
    assert(space);
1118
1119
    /* Remove current selection first */
1120
0
    if (rel_prev)
1121
0
        if (H5S_SELECT_RELEASE(space) < 0)
1122
0
            HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection");
1123
1124
    /* Set number of elements in selection */
1125
0
    space->select.num_elem = (hsize_t)H5S_GET_EXTENT_NPOINTS(space);
1126
1127
    /* Set selection type */
1128
0
    space->select.type = H5S_sel_all;
1129
1130
0
done:
1131
0
    FUNC_LEAVE_NOAPI(ret_value)
1132
0
} /* end H5S_select_all() */
1133
1134
/*--------------------------------------------------------------------------
1135
 NAME
1136
    H5Sselect_all
1137
 PURPOSE
1138
    Specify the entire extent is selected
1139
 USAGE
1140
    herr_t H5Sselect_all(dsid)
1141
        hid_t dsid;             IN: Dataspace ID of selection to modify
1142
 RETURNS
1143
    Non-negative on success/Negative on failure
1144
 DESCRIPTION
1145
    This function selects the entire extent for a dataspace.
1146
 GLOBAL VARIABLES
1147
 COMMENTS, BUGS, ASSUMPTIONS
1148
 EXAMPLES
1149
 REVISION LOG
1150
--------------------------------------------------------------------------*/
1151
herr_t
1152
H5Sselect_all(hid_t spaceid)
1153
0
{
1154
0
    H5S_t *space;               /* Dataspace to modify selection of */
1155
0
    herr_t ret_value = SUCCEED; /* return value */
1156
1157
0
    FUNC_ENTER_API(FAIL)
1158
1159
    /* Check args */
1160
0
    if (NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
1161
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace");
1162
1163
    /* Call internal routine to do the work */
1164
0
    if (H5S_select_all(space, true) < 0)
1165
0
        HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection");
1166
1167
0
done:
1168
0
    FUNC_LEAVE_API(ret_value)
1169
0
} /* end H5Sselect_all() */