Coverage Report

Created: 2024-06-18 06:29

/src/hdf5/src/H5Pdcpl.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 COPYING 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
 *
15
 * Created:     H5Pdcpl.c
16
 *
17
 * Purpose:     Dataset creation property list class routines
18
 *
19
 *-------------------------------------------------------------------------
20
 */
21
22
/****************/
23
/* Module Setup */
24
/****************/
25
26
#include "H5Pmodule.h" /* This source code file is part of the H5P module */
27
#define H5D_FRIEND     /* Suppress error about including H5Dpkg        */
28
29
/***********/
30
/* Headers */
31
/***********/
32
#include "H5private.h"   /* Generic Functions                        */
33
#include "H5Dpkg.h"      /* Datasets                                 */
34
#include "H5Eprivate.h"  /* Error handling                           */
35
#include "H5FLprivate.h" /* Free Lists                               */
36
#include "H5Iprivate.h"  /* IDs                                      */
37
#include "H5MMprivate.h" /* Memory management                        */
38
#include "H5Oprivate.h"  /* Object headers                           */
39
#include "H5Ppkg.h"      /* Property lists                           */
40
#include "H5Sprivate.h"  /* Dataspaces                               */
41
#include "H5Tprivate.h"  /* Datatypes                                */
42
#include "H5VMprivate.h" /* Vectors and arrays                       */
43
#include "H5Zprivate.h"  /* Data filters                             */
44
45
/****************/
46
/* Local Macros */
47
/****************/
48
49
/* Define default layout information */
50
#define H5D_DEF_STORAGE_COMPACT_INIT                                                                         \
51
    {                                                                                                        \
52
        false, (size_t)0, NULL                                                                               \
53
    }
54
#define H5D_DEF_STORAGE_CONTIG_INIT                                                                          \
55
    {                                                                                                        \
56
        HADDR_UNDEF, (hsize_t)0                                                                              \
57
    }
58
#define H5D_DEF_STORAGE_CHUNK_INIT                                                                           \
59
    {                                                                                                        \
60
        H5D_CHUNK_IDX_BTREE, HADDR_UNDEF, H5D_COPS_BTREE,                                                    \
61
        {                                                                                                    \
62
            {                                                                                                \
63
                HADDR_UNDEF, NULL                                                                            \
64
            }                                                                                                \
65
        }                                                                                                    \
66
    }
67
#define H5D_DEF_LAYOUT_CHUNK_INIT                                                                            \
68
    {                                                                                                        \
69
        H5D_CHUNK_IDX_BTREE, (uint8_t)0, (unsigned)0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    \
70
                                                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},      \
71
            (unsigned)0, (uint32_t)0, (hsize_t)0, (hsize_t)0,                                                \
72
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                                              \
73
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},                                                \
74
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                                              \
75
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},                                                \
76
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                                              \
77
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},                                                \
78
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                                              \
79
             0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},                                                \
80
        {                                                                                                    \
81
            {                                                                                                \
82
                {                                                                                            \
83
                    (uint8_t)0                                                                               \
84
                }                                                                                            \
85
            }                                                                                                \
86
        }                                                                                                    \
87
    }
88
#define H5D_DEF_STORAGE_VIRTUAL_INIT                                                                         \
89
    {                                                                                                        \
90
        {HADDR_UNDEF, 0}, 0, NULL, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                       \
91
                                       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},                      \
92
            H5D_VDS_ERROR, HSIZE_UNDEF, -1, -1, false                                                        \
93
    }
94
#define H5D_DEF_STORAGE_COMPACT                                                                              \
95
    {                                                                                                        \
96
        H5D_COMPACT,                                                                                         \
97
        {                                                                                                    \
98
            .compact = H5D_DEF_STORAGE_COMPACT_INIT                                                          \
99
        }                                                                                                    \
100
    }
101
#define H5D_DEF_STORAGE_CONTIG                                                                               \
102
    {                                                                                                        \
103
        H5D_CONTIGUOUS,                                                                                      \
104
        {                                                                                                    \
105
            .contig = H5D_DEF_STORAGE_CONTIG_INIT                                                            \
106
        }                                                                                                    \
107
    }
108
#define H5D_DEF_STORAGE_CHUNK                                                                                \
109
    {                                                                                                        \
110
        H5D_CHUNKED,                                                                                         \
111
        {                                                                                                    \
112
            .chunk = H5D_DEF_STORAGE_CHUNK_INIT                                                              \
113
        }                                                                                                    \
114
    }
115
#define H5D_DEF_STORAGE_VIRTUAL                                                                              \
116
    {                                                                                                        \
117
        H5D_VIRTUAL,                                                                                         \
118
        {                                                                                                    \
119
            .virt = H5D_DEF_STORAGE_VIRTUAL_INIT                                                             \
120
        }                                                                                                    \
121
    }
122
#define H5D_DEF_LAYOUT_COMPACT                                                                               \
123
    {                                                                                                        \
124
        H5D_COMPACT, H5O_LAYOUT_VERSION_DEFAULT, H5D_LOPS_COMPACT, {H5D_DEF_LAYOUT_CHUNK_INIT},              \
125
            H5D_DEF_STORAGE_COMPACT                                                                          \
126
    }
127
#define H5D_DEF_LAYOUT_CONTIG                                                                                \
128
    {                                                                                                        \
129
        H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_DEFAULT, H5D_LOPS_CONTIG, {H5D_DEF_LAYOUT_CHUNK_INIT},            \
130
            H5D_DEF_STORAGE_CONTIG                                                                           \
131
    }
132
#define H5D_DEF_LAYOUT_CHUNK                                                                                 \
133
    {                                                                                                        \
134
        H5D_CHUNKED, H5O_LAYOUT_VERSION_DEFAULT, H5D_LOPS_CHUNK, {H5D_DEF_LAYOUT_CHUNK_INIT},                \
135
            H5D_DEF_STORAGE_CHUNK                                                                            \
136
    }
137
#define H5D_DEF_LAYOUT_VIRTUAL                                                                               \
138
    {                                                                                                        \
139
        H5D_VIRTUAL, H5O_LAYOUT_VERSION_4, H5D_LOPS_VIRTUAL, {H5D_DEF_LAYOUT_CHUNK_INIT},                    \
140
            H5D_DEF_STORAGE_VIRTUAL                                                                          \
141
    }
142
143
/* ========  Dataset creation properties ======== */
144
/* Definitions for storage layout property */
145
1
#define H5D_CRT_LAYOUT_SIZE  sizeof(H5O_layout_t)
146
#define H5D_CRT_LAYOUT_DEF   H5D_DEF_LAYOUT_CONTIG
147
1
#define H5D_CRT_LAYOUT_SET   H5P__dcrt_layout_set
148
1
#define H5D_CRT_LAYOUT_GET   H5P__dcrt_layout_get
149
1
#define H5D_CRT_LAYOUT_ENC   H5P__dcrt_layout_enc
150
1
#define H5D_CRT_LAYOUT_DEC   H5P__dcrt_layout_dec
151
1
#define H5D_CRT_LAYOUT_DEL   H5P__dcrt_layout_del
152
1
#define H5D_CRT_LAYOUT_COPY  H5P__dcrt_layout_copy
153
1
#define H5D_CRT_LAYOUT_CMP   H5P__dcrt_layout_cmp
154
1
#define H5D_CRT_LAYOUT_CLOSE H5P__dcrt_layout_close
155
/* Definitions for fill value.  size=0 means fill value will be 0 as
156
 * library default; size=-1 means fill value is undefined. */
157
1
#define H5D_CRT_FILL_VALUE_SIZE sizeof(H5O_fill_t)
158
#define H5D_CRT_FILL_VALUE_DEF                                                                               \
159
    {                                                                                                        \
160
        {0, NULL, H5O_NULL_ID, {{0, HADDR_UNDEF}}}, H5O_FILL_VERSION_2, NULL, 0, NULL, H5D_ALLOC_TIME_LATE,  \
161
            H5D_FILL_TIME_IFSET, false                                                                       \
162
    }
163
1
#define H5D_CRT_FILL_VALUE_SET   H5P__dcrt_fill_value_set
164
1
#define H5D_CRT_FILL_VALUE_GET   H5P__dcrt_fill_value_get
165
1
#define H5D_CRT_FILL_VALUE_ENC   H5P__dcrt_fill_value_enc
166
1
#define H5D_CRT_FILL_VALUE_DEC   H5P__dcrt_fill_value_dec
167
1
#define H5D_CRT_FILL_VALUE_DEL   H5P__dcrt_fill_value_del
168
1
#define H5D_CRT_FILL_VALUE_COPY  H5P__dcrt_fill_value_copy
169
1
#define H5D_CRT_FILL_VALUE_CMP   H5P_fill_value_cmp
170
1
#define H5D_CRT_FILL_VALUE_CLOSE H5P__dcrt_fill_value_close
171
/* Definitions for space allocation time state */
172
1
#define H5D_CRT_ALLOC_TIME_STATE_SIZE sizeof(unsigned)
173
#define H5D_CRT_ALLOC_TIME_STATE_DEF  1
174
1
#define H5D_CRT_ALLOC_TIME_STATE_ENC  H5P__encode_unsigned
175
1
#define H5D_CRT_ALLOC_TIME_STATE_DEC  H5P__decode_unsigned
176
/* Definitions for external file list */
177
1
#define H5D_CRT_EXT_FILE_LIST_SIZE sizeof(H5O_efl_t)
178
#define H5D_CRT_EXT_FILE_LIST_DEF                                                                            \
179
    {                                                                                                        \
180
        HADDR_UNDEF, 0, 0, NULL                                                                              \
181
    }
182
1
#define H5D_CRT_EXT_FILE_LIST_SET   H5P__dcrt_ext_file_list_set
183
1
#define H5D_CRT_EXT_FILE_LIST_GET   H5P__dcrt_ext_file_list_get
184
1
#define H5D_CRT_EXT_FILE_LIST_ENC   H5P__dcrt_ext_file_list_enc
185
1
#define H5D_CRT_EXT_FILE_LIST_DEC   H5P__dcrt_ext_file_list_dec
186
1
#define H5D_CRT_EXT_FILE_LIST_DEL   H5P__dcrt_ext_file_list_del
187
1
#define H5D_CRT_EXT_FILE_LIST_COPY  H5P__dcrt_ext_file_list_copy
188
1
#define H5D_CRT_EXT_FILE_LIST_CMP   H5P__dcrt_ext_file_list_cmp
189
1
#define H5D_CRT_EXT_FILE_LIST_CLOSE H5P__dcrt_ext_file_list_close
190
/* Definitions for dataset object header minimization */
191
1
#define H5D_CRT_MIN_DSET_HDR_SIZE_SIZE sizeof(bool)
192
#define H5D_CRT_MIN_DSET_HDR_SIZE_DEF  false
193
1
#define H5D_CRT_MIN_DSET_HDR_SIZE_ENC  H5P__encode_bool
194
1
#define H5D_CRT_MIN_DSET_HDR_SIZE_DEC  H5P__decode_bool
195
196
/******************/
197
/* Local Typedefs */
198
/******************/
199
200
/********************/
201
/* Package Typedefs */
202
/********************/
203
204
/********************/
205
/* Local Prototypes */
206
/********************/
207
208
/* General routines */
209
static herr_t H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout);
210
211
/* Property class callbacks */
212
static herr_t H5P__dcrt_reg_prop(H5P_genclass_t *pclass);
213
214
/* Property callbacks */
215
static herr_t H5P__dcrt_layout_set(hid_t prop_id, const char *name, size_t size, void *value);
216
static herr_t H5P__dcrt_layout_get(hid_t prop_id, const char *name, size_t size, void *value);
217
static herr_t H5P__dcrt_layout_enc(const void *value, void **pp, size_t *size);
218
static herr_t H5P__dcrt_layout_dec(const void **pp, void *value);
219
static herr_t H5P__dcrt_layout_del(hid_t prop_id, const char *name, size_t size, void *value);
220
static herr_t H5P__dcrt_layout_copy(const char *name, size_t size, void *value);
221
static int    H5P__dcrt_layout_cmp(const void *value1, const void *value2, size_t size);
222
static herr_t H5P__dcrt_layout_close(const char *name, size_t size, void *value);
223
static herr_t H5P__dcrt_fill_value_set(hid_t prop_id, const char *name, size_t size, void *value);
224
static herr_t H5P__dcrt_fill_value_get(hid_t prop_id, const char *name, size_t size, void *value);
225
static herr_t H5P__dcrt_fill_value_enc(const void *value, void **pp, size_t *size);
226
static herr_t H5P__dcrt_fill_value_dec(const void **pp, void *value);
227
static herr_t H5P__dcrt_fill_value_del(hid_t prop_id, const char *name, size_t size, void *value);
228
static herr_t H5P__dcrt_fill_value_copy(const char *name, size_t size, void *value);
229
static herr_t H5P__dcrt_fill_value_close(const char *name, size_t size, void *value);
230
static herr_t H5P__dcrt_ext_file_list_set(hid_t prop_id, const char *name, size_t size, void *value);
231
static herr_t H5P__dcrt_ext_file_list_get(hid_t prop_id, const char *name, size_t size, void *value);
232
static herr_t H5P__dcrt_ext_file_list_enc(const void *value, void **pp, size_t *size);
233
static herr_t H5P__dcrt_ext_file_list_dec(const void **pp, void *value);
234
static herr_t H5P__dcrt_ext_file_list_del(hid_t prop_id, const char *name, size_t size, void *value);
235
static herr_t H5P__dcrt_ext_file_list_copy(const char *name, size_t size, void *value);
236
static int    H5P__dcrt_ext_file_list_cmp(const void *value1, const void *value2, size_t size);
237
static herr_t H5P__dcrt_ext_file_list_close(const char *name, size_t size, void *value);
238
239
/*********************/
240
/* Package Variables */
241
/*********************/
242
243
/* Dataset creation property list class library initialization object */
244
const H5P_libclass_t H5P_CLS_DCRT[1] = {{
245
    "dataset create",        /* Class name for debugging     */
246
    H5P_TYPE_DATASET_CREATE, /* Class type                   */
247
248
    &H5P_CLS_OBJECT_CREATE_g,     /* Parent class                 */
249
    &H5P_CLS_DATASET_CREATE_g,    /* Pointer to class             */
250
    &H5P_CLS_DATASET_CREATE_ID_g, /* Pointer to class ID          */
251
    &H5P_LST_DATASET_CREATE_ID_g, /* Pointer to default property list ID */
252
    H5P__dcrt_reg_prop,           /* Default property registration routine */
253
254
    NULL, /* Class creation callback      */
255
    NULL, /* Class creation callback info */
256
    NULL, /* Class copy callback          */
257
    NULL, /* Class copy callback info     */
258
    NULL, /* Class close callback         */
259
    NULL  /* Class close callback info    */
260
}};
261
262
/*****************************/
263
/* Library Private Variables */
264
/*****************************/
265
266
/* Declare extern the free list to manage blocks of type conversion data */
267
H5FL_BLK_EXTERN(type_conv);
268
269
/***************************/
270
/* Local Private Variables */
271
/***************************/
272
273
/* Property value defaults */
274
static const H5O_layout_t H5D_def_layout_g = H5D_CRT_LAYOUT_DEF;     /* Default storage layout */
275
static const H5O_fill_t   H5D_def_fill_g   = H5D_CRT_FILL_VALUE_DEF; /* Default fill value */
276
static const unsigned     H5D_def_alloc_time_state_g =
277
    H5D_CRT_ALLOC_TIME_STATE_DEF;                                     /* Default allocation time state */
278
static const H5O_efl_t H5D_def_efl_g = H5D_CRT_EXT_FILE_LIST_DEF;     /* Default external file list */
279
static const unsigned H5O_ohdr_min_g = H5D_CRT_MIN_DSET_HDR_SIZE_DEF; /* Default object header minimization */
280
281
/* Defaults for each type of layout */
282
static const H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT;
283
static const H5O_layout_t H5D_def_layout_contig_g  = H5D_DEF_LAYOUT_CONTIG;
284
static const H5O_layout_t H5D_def_layout_chunk_g   = H5D_DEF_LAYOUT_CHUNK;
285
static const H5O_layout_t H5D_def_layout_virtual_g = H5D_DEF_LAYOUT_VIRTUAL;
286
287
/*-------------------------------------------------------------------------
288
 * Function:    H5P__dcrt_reg_prop
289
 *
290
 * Purpose:     Register the dataset creation property list class's properties
291
 *
292
 * Return:      Non-negative on success/Negative on failure
293
 *
294
 *-------------------------------------------------------------------------
295
 */
296
static herr_t
297
H5P__dcrt_reg_prop(H5P_genclass_t *pclass)
298
1
{
299
1
    herr_t ret_value = SUCCEED; /* Return value */
300
301
1
    FUNC_ENTER_PACKAGE
302
303
    /* Register the storage layout property */
304
1
    if (H5P__register_real(pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &H5D_def_layout_g, NULL,
305
1
                           H5D_CRT_LAYOUT_SET, H5D_CRT_LAYOUT_GET, H5D_CRT_LAYOUT_ENC, H5D_CRT_LAYOUT_DEC,
306
1
                           H5D_CRT_LAYOUT_DEL, H5D_CRT_LAYOUT_COPY, H5D_CRT_LAYOUT_CMP,
307
1
                           H5D_CRT_LAYOUT_CLOSE) < 0)
308
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
309
310
    /* Register the fill value property */
311
1
    if (H5P__register_real(pclass, H5D_CRT_FILL_VALUE_NAME, H5D_CRT_FILL_VALUE_SIZE, &H5D_def_fill_g, NULL,
312
1
                           H5D_CRT_FILL_VALUE_SET, H5D_CRT_FILL_VALUE_GET, H5D_CRT_FILL_VALUE_ENC,
313
1
                           H5D_CRT_FILL_VALUE_DEC, H5D_CRT_FILL_VALUE_DEL, H5D_CRT_FILL_VALUE_COPY,
314
1
                           H5D_CRT_FILL_VALUE_CMP, H5D_CRT_FILL_VALUE_CLOSE) < 0)
315
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
316
317
    /* Register the space allocation time state property */
318
1
    if (H5P__register_real(pclass, H5D_CRT_ALLOC_TIME_STATE_NAME, H5D_CRT_ALLOC_TIME_STATE_SIZE,
319
1
                           &H5D_def_alloc_time_state_g, NULL, NULL, NULL, H5D_CRT_ALLOC_TIME_STATE_ENC,
320
1
                           H5D_CRT_ALLOC_TIME_STATE_DEC, NULL, NULL, NULL, NULL) < 0)
321
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
322
323
    /* Register the external file list property */
324
1
    if (H5P__register_real(pclass, H5D_CRT_EXT_FILE_LIST_NAME, H5D_CRT_EXT_FILE_LIST_SIZE, &H5D_def_efl_g,
325
1
                           NULL, H5D_CRT_EXT_FILE_LIST_SET, H5D_CRT_EXT_FILE_LIST_GET,
326
1
                           H5D_CRT_EXT_FILE_LIST_ENC, H5D_CRT_EXT_FILE_LIST_DEC, H5D_CRT_EXT_FILE_LIST_DEL,
327
1
                           H5D_CRT_EXT_FILE_LIST_COPY, H5D_CRT_EXT_FILE_LIST_CMP,
328
1
                           H5D_CRT_EXT_FILE_LIST_CLOSE) < 0)
329
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
330
331
    /* Register the object header minimization property */
332
1
    if (H5P__register_real(pclass, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, H5D_CRT_MIN_DSET_HDR_SIZE_SIZE,
333
1
                           &H5O_ohdr_min_g, NULL, NULL, NULL, H5D_CRT_MIN_DSET_HDR_SIZE_ENC,
334
1
                           H5D_CRT_MIN_DSET_HDR_SIZE_DEC, NULL, NULL, NULL, NULL) < 0)
335
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class");
336
337
1
done:
338
1
    FUNC_LEAVE_NOAPI(ret_value)
339
1
} /* end H5P__dcrt_reg_prop() */
340
341
/*-------------------------------------------------------------------------
342
 * Function:    H5P__dcrt_layout_set
343
 *
344
 * Purpose:     Copies a layout property when it's set for a property list
345
 *
346
 * Return:      Success:        Non-negative
347
 *              Failure:        Negative
348
 *
349
 *-------------------------------------------------------------------------
350
 */
351
static herr_t
352
H5P__dcrt_layout_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
353
                     size_t H5_ATTR_UNUSED size, void *value)
354
52
{
355
52
    H5O_layout_t *layout = (H5O_layout_t *)value; /* Create local aliases for values */
356
52
    H5O_layout_t  new_layout;
357
52
    herr_t        ret_value = SUCCEED; /* Return value */
358
359
52
    FUNC_ENTER_PACKAGE
360
361
    /* Sanity check */
362
52
    assert(value);
363
364
    /* Make copy of layout */
365
52
    if (NULL == H5O_msg_copy(H5O_LAYOUT_ID, layout, &new_layout))
366
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy layout");
367
368
    /* Copy new layout message over old one */
369
52
    *layout = new_layout;
370
371
52
done:
372
52
    FUNC_LEAVE_NOAPI(ret_value)
373
52
} /* end H5P__dcrt_layout_set() */
374
375
/*-------------------------------------------------------------------------
376
 * Function:    H5P__dcrt_layout_get
377
 *
378
 * Purpose:     Copies a layout property when it's retrieved from a property list
379
 *
380
 * Return:      Success:        Non-negative
381
 *              Failure:        Negative
382
 *
383
 *-------------------------------------------------------------------------
384
 */
385
static herr_t
386
H5P__dcrt_layout_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
387
                     size_t H5_ATTR_UNUSED size, void *value)
388
1
{
389
1
    H5O_layout_t *layout = (H5O_layout_t *)value; /* Create local aliases for values */
390
1
    H5O_layout_t  new_layout;
391
1
    herr_t        ret_value = SUCCEED; /* Return value */
392
393
1
    FUNC_ENTER_PACKAGE
394
395
    /* Sanity check */
396
1
    assert(value);
397
398
    /* Make copy of layout */
399
1
    if (NULL == H5O_msg_copy(H5O_LAYOUT_ID, layout, &new_layout))
400
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy layout");
401
402
    /* Copy new layout message over old one */
403
1
    *layout = new_layout;
404
405
1
done:
406
1
    FUNC_LEAVE_NOAPI(ret_value)
407
1
} /* end H5P__dcrt_layout_get() */
408
409
/*-------------------------------------------------------------------------
410
 * Function:       H5P__dcrt_layout_enc
411
 *
412
 * Purpose:        Callback routine which is called whenever the layout
413
 *                 property in the dataset creation property list is
414
 *                 encoded.
415
 *
416
 * Return:     Success: Non-negative
417
 *       Failure: Negative
418
 *
419
 *-------------------------------------------------------------------------
420
 */
421
static herr_t
422
H5P__dcrt_layout_enc(const void *value, void **_pp, size_t *size)
423
0
{
424
0
    const H5O_layout_t *layout = (const H5O_layout_t *)value; /* Create local aliases for values */
425
0
    uint8_t           **pp     = (uint8_t **)_pp;
426
0
    uint8_t            *tmp_p;
427
0
    size_t              tmp_size;
428
0
    size_t              u;                   /* Local index variable */
429
0
    herr_t              ret_value = SUCCEED; /* Return value */
430
431
0
    FUNC_ENTER_PACKAGE
432
433
    /* Sanity check */
434
0
    assert(layout);
435
0
    assert(size);
436
437
0
    if (NULL != *pp) {
438
        /* Encode layout type */
439
0
        *(*pp)++ = (uint8_t)layout->type;
440
0
        *size += sizeof(uint8_t);
441
442
        /* If layout is chunked, encode chunking structure */
443
0
        if (H5D_CHUNKED == layout->type) {
444
            /* Encode rank */
445
0
            *(*pp)++ = (uint8_t)layout->u.chunk.ndims;
446
0
            *size += sizeof(uint8_t);
447
448
            /* Encode chunk dims */
449
0
            HDcompile_assert(sizeof(uint32_t) == sizeof(layout->u.chunk.dim[0]));
450
0
            for (u = 0; u < (size_t)layout->u.chunk.ndims; u++) {
451
0
                UINT32ENCODE(*pp, layout->u.chunk.dim[u]);
452
0
                *size += sizeof(uint32_t);
453
0
            } /* end for */
454
0
        }     /* end if */
455
0
        else if (H5D_VIRTUAL == layout->type) {
456
0
            uint64_t nentries = (uint64_t)layout->storage.u.virt.list_nused;
457
458
            /* Encode number of entries */
459
0
            UINT64ENCODE(*pp, nentries);
460
0
            *size += (size_t)8;
461
462
            /* Iterate over entries */
463
0
            for (u = 0; u < layout->storage.u.virt.list_nused; u++) {
464
                /* Source file name */
465
0
                tmp_size = strlen(layout->storage.u.virt.list[u].source_file_name) + (size_t)1;
466
0
                H5MM_memcpy(*pp, layout->storage.u.virt.list[u].source_file_name, tmp_size);
467
0
                *pp += tmp_size;
468
0
                *size += tmp_size;
469
470
                /* Source dataset name */
471
0
                tmp_size = strlen(layout->storage.u.virt.list[u].source_dset_name) + (size_t)1;
472
0
                H5MM_memcpy(*pp, layout->storage.u.virt.list[u].source_dset_name, tmp_size);
473
0
                *pp += tmp_size;
474
0
                *size += tmp_size;
475
476
                /* Source selection.  Note that we are not passing the real
477
                 * allocated size because we do not know it.  H5P__encode should
478
                 * have verified that the buffer is large enough for the entire
479
                 * list before we get here. */
480
0
                tmp_size = (size_t)-1;
481
0
                tmp_p    = *pp;
482
0
                if (H5S_encode(layout->storage.u.virt.list[u].source_select, pp, &tmp_size) < 0)
483
0
                    HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize source selection");
484
0
                *size += (size_t)(*pp - tmp_p);
485
486
                /* Virtual dataset selection.  Same notes as above apply. */
487
0
                tmp_size = (size_t)-1;
488
0
                tmp_p    = *pp;
489
0
                if (H5S_encode(layout->storage.u.virt.list[u].source_dset.virtual_select, pp, &tmp_size) < 0)
490
0
                    HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize virtual selection");
491
0
                *size += (size_t)(*pp - tmp_p);
492
0
            } /* end for */
493
0
        }     /* end if */
494
0
    }         /* end if */
495
0
    else {
496
        /* Size of layout type */
497
0
        *size += sizeof(uint8_t);
498
499
        /* If layout is chunked, calculate chunking structure */
500
0
        if (H5D_CHUNKED == layout->type) {
501
0
            *size += sizeof(uint8_t);
502
0
            *size += layout->u.chunk.ndims * sizeof(uint32_t);
503
0
        } /* end if */
504
0
        else if (H5D_VIRTUAL == layout->type) {
505
            /* Calculate size of virtual layout info */
506
            /* number of entries */
507
0
            *size += (size_t)8;
508
509
            /* Iterate over entries */
510
0
            for (u = 0; u < layout->storage.u.virt.list_nused; u++) {
511
                /* Source file name */
512
0
                tmp_size = strlen(layout->storage.u.virt.list[u].source_file_name) + (size_t)1;
513
0
                *size += tmp_size;
514
515
                /* Source dataset name */
516
0
                tmp_size = strlen(layout->storage.u.virt.list[u].source_dset_name) + (size_t)1;
517
0
                *size += tmp_size;
518
519
                /* Source selection */
520
0
                tmp_size = (size_t)0;
521
0
                tmp_p    = NULL;
522
0
                if (H5S_encode(layout->storage.u.virt.list[u].source_select, &tmp_p, &tmp_size) < 0)
523
0
                    HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize source selection");
524
0
                *size += tmp_size;
525
526
                /* Virtual dataset selection */
527
0
                tmp_size = (size_t)0;
528
0
                tmp_p    = NULL;
529
0
                if (H5S_encode(layout->storage.u.virt.list[u].source_dset.virtual_select, &tmp_p, &tmp_size) <
530
0
                    0)
531
0
                    HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "unable to serialize virtual selection");
532
0
                *size += tmp_size;
533
0
            } /* end for */
534
0
        }     /* end if */
535
0
    }         /* end else */
536
537
0
done:
538
0
    FUNC_LEAVE_NOAPI(ret_value)
539
0
} /* end H5P__dcrt_layout_enc() */
540
541
/*-------------------------------------------------------------------------
542
 * Function:       H5P__dcrt_layout_dec
543
 *
544
 * Purpose:        Callback routine which is called whenever the layout
545
 *                 property in the dataset creation property list is
546
 *                 decoded.
547
 *
548
 * Return:     Success: Non-negative
549
 *       Failure: Negative
550
 *
551
 *-------------------------------------------------------------------------
552
 */
553
static herr_t
554
H5P__dcrt_layout_dec(const void **_pp, void *value)
555
0
{
556
0
    const H5O_layout_t *layout;     /* Storage layout */
557
0
    H5O_layout_t        tmp_layout; /* Temporary local layout structure */
558
0
    H5D_layout_t        type;       /* Layout type */
559
0
    const uint8_t     **pp        = (const uint8_t **)_pp;
560
0
    herr_t              ret_value = SUCCEED; /* Return value */
561
562
0
    FUNC_ENTER_PACKAGE
563
564
    /* Sanity checks */
565
0
    assert(pp);
566
0
    assert(*pp);
567
0
    assert(value);
568
569
    /* Decode layout type */
570
0
    type = (H5D_layout_t) * (*pp)++;
571
572
    /* set default layout in case the type is compact or contiguous, otherwise
573
     * decode the chunked structure and set chunked layout */
574
0
    switch (type) {
575
0
        case H5D_COMPACT:
576
0
            layout = &H5D_def_layout_compact_g;
577
0
            break;
578
579
0
        case H5D_CONTIGUOUS:
580
0
            layout = &H5D_def_layout_contig_g;
581
0
            break;
582
583
0
        case H5D_CHUNKED: {
584
0
            unsigned ndims; /* Number of chunk dimensions */
585
586
            /* Decode the number of chunk dimensions */
587
0
            ndims = *(*pp)++;
588
589
            /* default chunk layout */
590
0
            if (0 == ndims)
591
0
                layout = &H5D_def_layout_chunk_g;
592
0
            else {          /* chunk layout structure is encoded*/
593
0
                unsigned u; /* Local index variable */
594
595
                /* Initialize to default values */
596
0
                tmp_layout = H5D_def_layout_chunk_g;
597
598
                /* Set rank & dimensions */
599
0
                tmp_layout.u.chunk.ndims = (unsigned)ndims;
600
0
                for (u = 0; u < ndims; u++)
601
0
                    UINT32DECODE(*pp, tmp_layout.u.chunk.dim[u]);
602
603
                /* Point at the newly set up struct */
604
0
                layout = &tmp_layout;
605
0
            } /* end else */
606
0
        } break;
607
608
0
        case H5D_VIRTUAL: {
609
0
            uint64_t nentries; /* Number of VDS mappings */
610
611
            /* Decode number of entries */
612
0
            UINT64DECODE(*pp, nentries);
613
614
0
            if (nentries == (uint64_t)0)
615
                /* Just use the default struct */
616
0
                layout = &H5D_def_layout_virtual_g;
617
0
            else {
618
0
                size_t tmp_size;
619
0
                size_t u; /* Local index variable */
620
621
                /* Initialize to default values */
622
0
                tmp_layout = H5D_def_layout_virtual_g;
623
624
                /* Allocate entry list */
625
0
                if (NULL == (tmp_layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_calloc(
626
0
                                 (size_t)nentries * sizeof(H5O_storage_virtual_ent_t))))
627
0
                    HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "unable to allocate heap block");
628
0
                tmp_layout.storage.u.virt.list_nalloc = (size_t)nentries;
629
0
                tmp_layout.storage.u.virt.list_nused  = (size_t)nentries;
630
631
                /* Decode each entry */
632
0
                for (u = 0; u < (size_t)nentries; u++) {
633
                    /* Source file name */
634
0
                    tmp_size = strlen((const char *)*pp) + 1;
635
0
                    if (NULL ==
636
0
                        (tmp_layout.storage.u.virt.list[u].source_file_name = (char *)H5MM_malloc(tmp_size)))
637
0
                        HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL,
638
0
                                    "unable to allocate memory for source file name");
639
0
                    H5MM_memcpy(tmp_layout.storage.u.virt.list[u].source_file_name, *pp, tmp_size);
640
0
                    *pp += tmp_size;
641
642
                    /* Source dataset name */
643
0
                    tmp_size = strlen((const char *)*pp) + 1;
644
0
                    if (NULL ==
645
0
                        (tmp_layout.storage.u.virt.list[u].source_dset_name = (char *)H5MM_malloc(tmp_size)))
646
0
                        HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL,
647
0
                                    "unable to allocate memory for source dataset name");
648
0
                    H5MM_memcpy(tmp_layout.storage.u.virt.list[u].source_dset_name, *pp, tmp_size);
649
0
                    *pp += tmp_size;
650
651
                    /* Source selection */
652
0
                    if (NULL == (tmp_layout.storage.u.virt.list[u].source_select = H5S_decode(pp)))
653
0
                        HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "can't decode source space selection");
654
0
                    tmp_layout.storage.u.virt.list[u].source_space_status = H5O_VIRTUAL_STATUS_USER;
655
656
                    /* Virtual selection */
657
0
                    if (NULL ==
658
0
                        (tmp_layout.storage.u.virt.list[u].source_dset.virtual_select = H5S_decode(pp)))
659
0
                        HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "can't decode virtual space selection");
660
0
                    tmp_layout.storage.u.virt.list[u].virtual_space_status = H5O_VIRTUAL_STATUS_USER;
661
662
                    /* Parse source file and dataset names for "printf"
663
                     * style format specifiers */
664
0
                    if (H5D_virtual_parse_source_name(
665
0
                            tmp_layout.storage.u.virt.list[u].source_file_name,
666
0
                            &tmp_layout.storage.u.virt.list[u].parsed_source_file_name,
667
0
                            &tmp_layout.storage.u.virt.list[u].psfn_static_strlen,
668
0
                            &tmp_layout.storage.u.virt.list[u].psfn_nsubs) < 0)
669
0
                        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source file name");
670
0
                    if (H5D_virtual_parse_source_name(
671
0
                            tmp_layout.storage.u.virt.list[u].source_dset_name,
672
0
                            &tmp_layout.storage.u.virt.list[u].parsed_source_dset_name,
673
0
                            &tmp_layout.storage.u.virt.list[u].psdn_static_strlen,
674
0
                            &tmp_layout.storage.u.virt.list[u].psdn_nsubs) < 0)
675
0
                        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source dataset name");
676
677
                    /* Set source names in source_dset struct */
678
0
                    if ((tmp_layout.storage.u.virt.list[u].psfn_nsubs == 0) &&
679
0
                        (tmp_layout.storage.u.virt.list[u].psdn_nsubs == 0)) {
680
0
                        if (tmp_layout.storage.u.virt.list[u].parsed_source_file_name)
681
0
                            tmp_layout.storage.u.virt.list[u].source_dset.file_name =
682
0
                                tmp_layout.storage.u.virt.list[u].parsed_source_file_name->name_segment;
683
0
                        else
684
0
                            tmp_layout.storage.u.virt.list[u].source_dset.file_name =
685
0
                                tmp_layout.storage.u.virt.list[u].source_file_name;
686
0
                        if (tmp_layout.storage.u.virt.list[u].parsed_source_dset_name)
687
0
                            tmp_layout.storage.u.virt.list[u].source_dset.dset_name =
688
0
                                tmp_layout.storage.u.virt.list[u].parsed_source_dset_name->name_segment;
689
0
                        else
690
0
                            tmp_layout.storage.u.virt.list[u].source_dset.dset_name =
691
0
                                tmp_layout.storage.u.virt.list[u].source_dset_name;
692
0
                    } /* end if */
693
694
                    /* unlim_dim fields */
695
0
                    tmp_layout.storage.u.virt.list[u].unlim_dim_source =
696
0
                        H5S_get_select_unlim_dim(tmp_layout.storage.u.virt.list[u].source_select);
697
0
                    tmp_layout.storage.u.virt.list[u].unlim_dim_virtual = H5S_get_select_unlim_dim(
698
0
                        tmp_layout.storage.u.virt.list[u].source_dset.virtual_select);
699
0
                    tmp_layout.storage.u.virt.list[u].unlim_extent_source  = HSIZE_UNDEF;
700
0
                    tmp_layout.storage.u.virt.list[u].unlim_extent_virtual = HSIZE_UNDEF;
701
0
                    tmp_layout.storage.u.virt.list[u].clip_size_source     = HSIZE_UNDEF;
702
0
                    tmp_layout.storage.u.virt.list[u].clip_size_virtual    = HSIZE_UNDEF;
703
704
                    /* Clipped selections */
705
0
                    if (tmp_layout.storage.u.virt.list[u].unlim_dim_virtual < 0) {
706
0
                        tmp_layout.storage.u.virt.list[u].source_dset.clipped_source_select =
707
0
                            tmp_layout.storage.u.virt.list[u].source_select;
708
0
                        tmp_layout.storage.u.virt.list[u].source_dset.clipped_virtual_select =
709
0
                            tmp_layout.storage.u.virt.list[u].source_dset.virtual_select;
710
0
                    } /* end if */
711
712
                    /* Update min_dims */
713
0
                    if (H5D_virtual_update_min_dims(&tmp_layout, u) < 0)
714
0
                        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL,
715
0
                                    "unable to update virtual dataset minimum dimensions");
716
0
                } /* end for */
717
718
                /* Point at the newly set up struct */
719
0
                layout = &tmp_layout;
720
0
            } /* end else */
721
0
        }     /* end block */
722
0
        break;
723
724
0
        case H5D_LAYOUT_ERROR:
725
0
        case H5D_NLAYOUTS:
726
0
        default:
727
0
            HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad layout type");
728
0
    } /* end switch */
729
730
    /* Set the value */
731
0
    H5MM_memcpy(value, layout, sizeof(H5O_layout_t));
732
733
0
done:
734
0
    FUNC_LEAVE_NOAPI(ret_value)
735
0
} /* end H5P__dcrt_layout_dec() */
736
737
/*-------------------------------------------------------------------------
738
 * Function:    H5P__dcrt_layout_del
739
 *
740
 * Purpose:     Frees memory used to store the layout property
741
 *
742
 * Return:      Success:        Non-negative
743
 *              Failure:        Negative
744
 *
745
 *-------------------------------------------------------------------------
746
 */
747
static herr_t
748
H5P__dcrt_layout_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
749
                     size_t H5_ATTR_UNUSED size, void *value)
750
52
{
751
52
    herr_t ret_value = SUCCEED; /* Return value */
752
753
52
    FUNC_ENTER_PACKAGE
754
755
    /* Sanity check */
756
52
    assert(value);
757
758
    /* Reset the old layout */
759
52
    if (H5O_msg_reset(H5O_LAYOUT_ID, value) < 0)
760
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release layout message");
761
762
52
done:
763
52
    FUNC_LEAVE_NOAPI(ret_value)
764
52
} /* end H5P__dcrt_layout_del() */
765
766
/*--------------------------------------------------------------------------
767
 * Function:    H5P__dcrt_layout_copy
768
 *
769
 * Purpose:     Copy the layout property
770
 *
771
 * Return:      Success:        Non-negative
772
 *              Failure:        Negative
773
 *
774
 *--------------------------------------------------------------------------
775
 */
776
static herr_t
777
H5P__dcrt_layout_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
778
92
{
779
92
    H5O_layout_t *layout = (H5O_layout_t *)value; /* Create local aliases for values */
780
92
    H5O_layout_t  new_layout;
781
92
    herr_t        ret_value = SUCCEED;
782
783
92
    FUNC_ENTER_PACKAGE
784
785
92
    assert(layout);
786
787
    /* Make copy of layout */
788
92
    if (NULL == H5O_msg_copy(H5O_LAYOUT_ID, layout, &new_layout))
789
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy layout");
790
791
    /* Set new layout message directly into property list */
792
92
    *layout = new_layout;
793
794
92
done:
795
92
    FUNC_LEAVE_NOAPI(ret_value)
796
92
} /* end H5P__dcrt_layout_copy() */
797
798
/*-------------------------------------------------------------------------
799
 * Function:       H5P__dcrt_layout_cmp
800
 *
801
 * Purpose:        Callback routine which is called whenever the layout
802
 *                 property in the dataset creation property list is
803
 *                 compared.
804
 *
805
 * Return:         positive if VALUE1 is greater than VALUE2, negative if
806
 *                      VALUE2 is greater than VALUE1 and zero if VALUE1 and
807
 *                      VALUE2 are equal.
808
 *
809
 *-------------------------------------------------------------------------
810
 */
811
static int
812
H5P__dcrt_layout_cmp(const void *_layout1, const void *_layout2, size_t H5_ATTR_UNUSED size)
813
0
{
814
0
    const H5O_layout_t *layout1 = (const H5O_layout_t *)_layout1, /* Create local aliases for values */
815
0
        *layout2                = (const H5O_layout_t *)_layout2;
816
0
    herr_t ret_value            = 0; /* Return value */
817
818
0
    FUNC_ENTER_PACKAGE_NOERR
819
820
    /* Sanity check */
821
0
    assert(layout1);
822
0
    assert(layout2);
823
0
    assert(size == sizeof(H5O_layout_t));
824
825
    /* Check for different layout type */
826
0
    if (layout1->type < layout2->type)
827
0
        HGOTO_DONE(-1);
828
0
    if (layout1->type > layout2->type)
829
0
        HGOTO_DONE(1);
830
831
    /* Compare non-dataset-specific fields in layout info */
832
0
    switch (layout1->type) {
833
0
        case H5D_COMPACT:
834
0
        case H5D_CONTIGUOUS:
835
0
            break;
836
837
0
        case H5D_CHUNKED: {
838
0
            unsigned u; /* Local index variable */
839
840
            /* Check the number of dimensions */
841
0
            if (layout1->u.chunk.ndims < layout2->u.chunk.ndims)
842
0
                HGOTO_DONE(-1);
843
0
            if (layout1->u.chunk.ndims > layout2->u.chunk.ndims)
844
0
                HGOTO_DONE(1);
845
846
            /* Compare the chunk dims */
847
0
            for (u = 0; u < layout1->u.chunk.ndims - 1; u++) {
848
0
                if (layout1->u.chunk.dim[u] < layout2->u.chunk.dim[u])
849
0
                    HGOTO_DONE(-1);
850
0
                if (layout1->u.chunk.dim[u] > layout2->u.chunk.dim[u])
851
0
                    HGOTO_DONE(1);
852
0
            } /* end for */
853
0
        }     /* end case */
854
0
        break;
855
856
0
        case H5D_VIRTUAL: {
857
0
            htri_t equal;
858
0
            int    strcmp_ret;
859
0
            size_t u; /* Local index variable */
860
861
            /* Compare number of mappings */
862
0
            if (layout1->storage.u.virt.list_nused < layout2->storage.u.virt.list_nused)
863
0
                HGOTO_DONE(-1);
864
0
            if (layout1->storage.u.virt.list_nused > layout2->storage.u.virt.list_nused)
865
0
                HGOTO_DONE(1);
866
867
            /* Iterate over mappings */
868
0
            for (u = 0; u < layout1->storage.u.virt.list_nused; u++) {
869
                /* Compare virtual spaces.  Note we cannot tell which is
870
                 * "greater", so just return 1 if different, -1 on failure.
871
                 */
872
0
                if ((equal = H5S_extent_equal(layout1->storage.u.virt.list[u].source_dset.virtual_select,
873
0
                                              layout2->storage.u.virt.list[u].source_dset.virtual_select)) <
874
0
                    0)
875
0
                    HGOTO_DONE(-1);
876
0
                if (!equal)
877
0
                    HGOTO_DONE(1);
878
0
                if ((equal = H5S_SELECT_SHAPE_SAME(
879
0
                         layout1->storage.u.virt.list[u].source_dset.virtual_select,
880
0
                         layout2->storage.u.virt.list[u].source_dset.virtual_select)) < 0)
881
0
                    HGOTO_DONE(-1);
882
0
                if (!equal)
883
0
                    HGOTO_DONE(1);
884
885
                /* Compare source file names */
886
0
                strcmp_ret = strcmp(layout1->storage.u.virt.list[u].source_file_name,
887
0
                                    layout2->storage.u.virt.list[u].source_file_name);
888
0
                if (strcmp_ret < 0)
889
0
                    HGOTO_DONE(-1);
890
0
                if (strcmp_ret > 0)
891
0
                    HGOTO_DONE(1);
892
893
                /* Compare source dataset names */
894
0
                strcmp_ret = strcmp(layout1->storage.u.virt.list[u].source_dset_name,
895
0
                                    layout2->storage.u.virt.list[u].source_dset_name);
896
0
                if (strcmp_ret < 0)
897
0
                    HGOTO_DONE(-1);
898
0
                if (strcmp_ret > 0)
899
0
                    HGOTO_DONE(1);
900
901
                /* Compare source spaces.  Note we cannot tell which is
902
                 * "greater", so just return 1 if different, -1 on failure.
903
                 */
904
0
                if ((equal = H5S_extent_equal(layout1->storage.u.virt.list[u].source_select,
905
0
                                              layout2->storage.u.virt.list[u].source_select)) < 0)
906
0
                    HGOTO_DONE(-1);
907
0
                if (!equal)
908
0
                    HGOTO_DONE(1);
909
0
                if ((equal = H5S_SELECT_SHAPE_SAME(layout1->storage.u.virt.list[u].source_select,
910
0
                                                   layout2->storage.u.virt.list[u].source_select)) < 0)
911
0
                    HGOTO_DONE(-1);
912
0
                if (!equal)
913
0
                    HGOTO_DONE(1);
914
0
            } /* end for */
915
0
        }     /* end block */
916
0
        break;
917
918
0
        case H5D_LAYOUT_ERROR:
919
0
        case H5D_NLAYOUTS:
920
0
        default:
921
0
            assert(0 && "Unknown layout type!");
922
0
    } /* end switch */
923
924
0
done:
925
0
    FUNC_LEAVE_NOAPI(ret_value)
926
0
} /* end H5P__dcrt_layout_cmp() */
927
928
/*-------------------------------------------------------------------------
929
 * Function:    H5P__dcrt_layout_close
930
 *
931
 * Purpose:     Frees memory used to store the layout property
932
 *
933
 * Return:      Success:        Non-negative
934
 *              Failure:        Negative
935
 *
936
 *-------------------------------------------------------------------------
937
 */
938
static herr_t
939
H5P__dcrt_layout_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
940
93
{
941
93
    herr_t ret_value = SUCCEED; /* Return value */
942
943
93
    FUNC_ENTER_PACKAGE
944
945
    /* Sanity check */
946
93
    assert(value);
947
948
    /* Reset the old layout */
949
93
    if (H5O_msg_reset(H5O_LAYOUT_ID, value) < 0)
950
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release layout message");
951
952
93
done:
953
93
    FUNC_LEAVE_NOAPI(ret_value)
954
93
} /* end H5P__dcrt_layout_close() */
955
956
/*-------------------------------------------------------------------------
957
 * Function:    H5P__dcrt_fill_value_set
958
 *
959
 * Purpose:     Copies a fill value property when it's set for a property list
960
 *
961
 * Return:      Success:        Non-negative
962
 *              Failure:        Negative
963
 *
964
 *-------------------------------------------------------------------------
965
 */
966
static herr_t
967
H5P__dcrt_fill_value_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
968
                         size_t H5_ATTR_UNUSED size, void *value)
969
52
{
970
52
    H5O_fill_t *fill = (H5O_fill_t *)value; /* Create local aliases for values */
971
52
    H5O_fill_t  new_fill;
972
52
    herr_t      ret_value = SUCCEED; /* Return value */
973
974
52
    FUNC_ENTER_PACKAGE
975
976
    /* Sanity check */
977
52
    assert(value);
978
979
    /* Make copy of fill value */
980
52
    if (NULL == H5O_msg_copy(H5O_FILL_ID, fill, &new_fill))
981
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy fill value");
982
983
    /* Copy new fill value message over old one */
984
52
    *fill = new_fill;
985
986
52
done:
987
52
    FUNC_LEAVE_NOAPI(ret_value)
988
52
} /* end H5P__dcrt_fill_value_set() */
989
990
/*-------------------------------------------------------------------------
991
 * Function:    H5P__dcrt_fill_value_get
992
 *
993
 * Purpose:     Copies a fill value property when it's retrieved from a property list
994
 *
995
 * Return:      Success:        Non-negative
996
 *              Failure:        Negative
997
 *
998
 *-------------------------------------------------------------------------
999
 */
1000
static herr_t
1001
H5P__dcrt_fill_value_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
1002
                         size_t H5_ATTR_UNUSED size, void *value)
1003
1
{
1004
1
    H5O_fill_t *fill = (H5O_fill_t *)value; /* Create local aliases for values */
1005
1
    H5O_fill_t  new_fill;
1006
1
    herr_t      ret_value = SUCCEED; /* Return value */
1007
1008
1
    FUNC_ENTER_PACKAGE
1009
1010
    /* Sanity check */
1011
1
    assert(value);
1012
1013
    /* Make copy of fill value */
1014
1
    if (NULL == H5O_msg_copy(H5O_FILL_ID, fill, &new_fill))
1015
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy fill value");
1016
1017
    /* Copy new fill value message over old one */
1018
1
    *fill = new_fill;
1019
1020
1
done:
1021
1
    FUNC_LEAVE_NOAPI(ret_value)
1022
1
} /* end H5P__dcrt_fill_value_get() */
1023
1024
/*-------------------------------------------------------------------------
1025
 * Function:       H5P__dcrt_fill_value_enc
1026
 *
1027
 * Purpose:        Callback routine which is called whenever the fill value
1028
 *                 property in the dataset creation property list is
1029
 *                 encoded.
1030
 *
1031
 * Return:     Success: Non-negative
1032
 *       Failure: Negative
1033
 *
1034
 *-------------------------------------------------------------------------
1035
 */
1036
static herr_t
1037
H5P__dcrt_fill_value_enc(const void *value, void **_pp, size_t *size)
1038
0
{
1039
0
    const H5O_fill_t *fill      = (const H5O_fill_t *)value; /* Create local aliases for values */
1040
0
    size_t            dt_size   = 0;                         /* Size of encoded datatype */
1041
0
    herr_t            ret_value = SUCCEED;                   /* Return value */
1042
0
    uint8_t         **pp        = (uint8_t **)_pp;
1043
0
    uint64_t          enc_value;
1044
0
    unsigned          enc_size = 0;
1045
1046
0
    FUNC_ENTER_PACKAGE
1047
1048
    /* Sanity check */
1049
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
1050
0
    HDcompile_assert(sizeof(ssize_t) <= sizeof(int64_t));
1051
0
    assert(fill);
1052
0
    assert(size);
1053
1054
0
    if (NULL != *pp) {
1055
        /* Encode alloc and fill time */
1056
0
        *(*pp)++ = (uint8_t)fill->alloc_time;
1057
0
        *(*pp)++ = (uint8_t)fill->fill_time;
1058
1059
        /* Encode size of fill value */
1060
0
        INT64ENCODE(*pp, fill->size);
1061
1062
        /* Encode the fill value & datatype */
1063
0
        if (fill->size > 0) {
1064
            /* Encode the fill value itself */
1065
0
            H5MM_memcpy(*pp, (uint8_t *)fill->buf, (size_t)fill->size);
1066
0
            *pp += fill->size;
1067
1068
            /* Encode fill value datatype */
1069
0
            assert(fill->type);
1070
1071
0
            if (H5T_encode(fill->type, NULL, &dt_size) < 0)
1072
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype");
1073
1074
            /* Encode the size of a size_t */
1075
0
            enc_value = (uint64_t)dt_size;
1076
0
            enc_size  = H5VM_limit_enc_size(enc_value);
1077
0
            assert(enc_size < 256);
1078
1079
            /* Encode the size */
1080
0
            *(*pp)++ = (uint8_t)enc_size;
1081
1082
            /* Encode the size of the encoded datatype */
1083
0
            UINT64ENCODE_VAR(*pp, enc_value, enc_size);
1084
1085
0
            if (H5T_encode(fill->type, *pp, &dt_size) < 0)
1086
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype");
1087
0
            *pp += dt_size;
1088
0
        } /* end if */
1089
0
    }     /* end if */
1090
1091
    /* Calculate size needed for encoding */
1092
0
    *size += 2;
1093
0
    *size += sizeof(int64_t);
1094
0
    if (fill->size > 0) {
1095
        /* The size of the fill value buffer */
1096
0
        *size += (size_t)fill->size;
1097
1098
        /* calculate those if they were not calculated earlier */
1099
0
        if (NULL == *pp) {
1100
            /* Get the size of the encoded datatype */
1101
0
            assert(fill->type);
1102
0
            if (H5T_encode(fill->type, NULL, &dt_size) < 0)
1103
0
                HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype");
1104
0
            enc_value = (uint64_t)dt_size;
1105
0
            enc_size  = H5VM_limit_enc_size(enc_value);
1106
0
        }
1107
0
        *size += (1 + enc_size);
1108
0
        *size += dt_size;
1109
0
    } /* end if */
1110
1111
0
done:
1112
0
    FUNC_LEAVE_NOAPI(ret_value)
1113
0
} /* end H5P__dcrt_fill_value_enc() */
1114
1115
/*-------------------------------------------------------------------------
1116
 * Function:       H5P__dcrt_fill_value_dec
1117
 *
1118
 * Purpose:        Callback routine which is called whenever the fill value
1119
 *                 property in the dataset creation property list is
1120
 *                 decoded.
1121
 *
1122
 * Return:     Success: Non-negative
1123
 *       Failure: Negative
1124
 *
1125
 *-------------------------------------------------------------------------
1126
 */
1127
static herr_t
1128
H5P__dcrt_fill_value_dec(const void **_pp, void *_value)
1129
0
{
1130
0
    H5O_fill_t     *fill      = (H5O_fill_t *)_value; /* Fill value */
1131
0
    const uint8_t **pp        = (const uint8_t **)_pp;
1132
0
    herr_t          ret_value = SUCCEED; /* Return value */
1133
1134
0
    FUNC_ENTER_PACKAGE
1135
1136
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
1137
0
    HDcompile_assert(sizeof(ssize_t) <= sizeof(int64_t));
1138
1139
    /* Set property to default value */
1140
0
    *fill = H5D_def_fill_g;
1141
1142
    /* Decode alloc and fill time */
1143
0
    fill->alloc_time = (H5D_alloc_time_t) * (*pp)++;
1144
0
    fill->fill_time  = (H5D_fill_time_t) * (*pp)++;
1145
1146
    /* Decode fill size */
1147
0
    INT64DECODE(*pp, fill->size);
1148
1149
    /* Check if there's a fill value */
1150
0
    if (fill->size > 0) {
1151
0
        size_t   dt_size = 0;
1152
0
        uint64_t enc_value;
1153
0
        unsigned enc_size;
1154
1155
        /* Allocate fill buffer and copy the contents in it */
1156
0
        if (NULL == (fill->buf = H5MM_malloc((size_t)fill->size)))
1157
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for fill value buffer");
1158
0
        H5MM_memcpy((uint8_t *)fill->buf, *pp, (size_t)fill->size);
1159
0
        *pp += fill->size;
1160
1161
0
        enc_size = *(*pp)++;
1162
0
        assert(enc_size < 256);
1163
1164
        /* Decode the size of encoded datatype */
1165
0
        UINT64DECODE_VAR(*pp, enc_value, enc_size);
1166
0
        dt_size = (size_t)enc_value;
1167
1168
        /* Decode type */
1169
0
        if (NULL == (fill->type = H5T_decode(dt_size, *pp)))
1170
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "can't decode fill value datatype");
1171
0
        *pp += dt_size;
1172
0
    } /* end if */
1173
1174
0
done:
1175
0
    FUNC_LEAVE_NOAPI(ret_value)
1176
0
} /* end H5P__dcrt_fill_value_dec() */
1177
1178
/*-------------------------------------------------------------------------
1179
 * Function:    H5P__dcrt_fill_value_del
1180
 *
1181
 * Purpose:     Frees memory used to store the fill value property
1182
 *
1183
 * Return:      Success:        Non-negative
1184
 *              Failure:        Negative
1185
 *
1186
 *-------------------------------------------------------------------------
1187
 */
1188
static herr_t
1189
H5P__dcrt_fill_value_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
1190
                         size_t H5_ATTR_UNUSED size, void *value)
1191
52
{
1192
52
    herr_t ret_value = SUCCEED; /* Return value */
1193
1194
52
    FUNC_ENTER_PACKAGE
1195
1196
    /* Sanity check */
1197
52
    assert(value);
1198
1199
    /* Reset the old fill value message */
1200
52
    if (H5O_msg_reset(H5O_FILL_ID, value) < 0)
1201
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release fill value message");
1202
1203
52
done:
1204
52
    FUNC_LEAVE_NOAPI(ret_value)
1205
52
} /* end H5P__dcrt_fill_value_del() */
1206
1207
/*--------------------------------------------------------------------------
1208
 * Function:    H5P__dcrt_fill_value_copy
1209
 *
1210
 * Purpose:     Copy the fill value property
1211
 *
1212
 * Return:      Success:        Non-negative
1213
 *              Failure:        Negative
1214
 *
1215
 *--------------------------------------------------------------------------
1216
 */
1217
static herr_t
1218
H5P__dcrt_fill_value_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
1219
92
{
1220
92
    H5O_fill_t *fill = (H5O_fill_t *)value; /* Create local aliases for values */
1221
92
    H5O_fill_t  new_fill;
1222
92
    herr_t      ret_value = SUCCEED;
1223
1224
92
    FUNC_ENTER_PACKAGE
1225
1226
92
    assert(fill);
1227
1228
    /* Make copy of fill value message */
1229
92
    if (NULL == H5O_msg_copy(H5O_FILL_ID, fill, &new_fill))
1230
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy fill value");
1231
1232
    /* Set new fill value message directly into property list */
1233
92
    *fill = new_fill;
1234
1235
92
done:
1236
92
    FUNC_LEAVE_NOAPI(ret_value)
1237
92
} /* end H5P__dcrt_fill_value_copy() */
1238
1239
/*-------------------------------------------------------------------------
1240
 * Function:       H5P_fill_value_cmp
1241
 *
1242
 * Purpose:        Callback routine which is called whenever the fill value
1243
 *                 property in the dataset creation property list is compared.
1244
 *
1245
 * Return:         positive if VALUE1 is greater than VALUE2, negative if
1246
 *                      VALUE2 is greater than VALUE1 and zero if VALUE1 and
1247
 *                      VALUE2 are equal.
1248
 *
1249
 *-------------------------------------------------------------------------
1250
 */
1251
int
1252
H5P_fill_value_cmp(const void *_fill1, const void *_fill2, size_t H5_ATTR_UNUSED size)
1253
52
{
1254
52
    const H5O_fill_t *fill1 = (const H5O_fill_t *)_fill1, /* Create local aliases for values */
1255
52
        *fill2              = (const H5O_fill_t *)_fill2;
1256
52
    int    cmp_value;     /* Value from comparison */
1257
52
    herr_t ret_value = 0; /* Return value */
1258
1259
52
    FUNC_ENTER_NOAPI_NOINIT_NOERR
1260
1261
    /* Sanity check */
1262
52
    assert(fill1);
1263
52
    assert(fill2);
1264
52
    assert(size == sizeof(H5O_fill_t));
1265
1266
    /* Check the size of fill values */
1267
52
    if (fill1->size < fill2->size)
1268
9
        HGOTO_DONE(-1);
1269
43
    if (fill1->size > fill2->size)
1270
0
        HGOTO_DONE(1);
1271
1272
    /* Check the types of the fill values */
1273
43
    if (fill1->type == NULL && fill2->type != NULL)
1274
0
        HGOTO_DONE(-1);
1275
43
    if (fill1->type != NULL && fill2->type == NULL)
1276
0
        HGOTO_DONE(1);
1277
43
    if (fill1->type != NULL)
1278
0
        if ((cmp_value = H5T_cmp(fill1->type, fill2->type, false)) != 0)
1279
0
            HGOTO_DONE(cmp_value);
1280
1281
    /* Check the fill values in the buffers */
1282
43
    if (fill1->buf == NULL && fill2->buf != NULL)
1283
0
        HGOTO_DONE(-1);
1284
43
    if (fill1->buf != NULL && fill2->buf == NULL)
1285
0
        HGOTO_DONE(1);
1286
43
    if (fill1->buf != NULL)
1287
0
        if ((cmp_value = memcmp(fill1->buf, fill2->buf, (size_t)fill1->size)) != 0)
1288
0
            HGOTO_DONE(cmp_value);
1289
1290
    /* Check the allocation time for the fill values */
1291
43
    if (fill1->alloc_time < fill2->alloc_time)
1292
0
        HGOTO_DONE(-1);
1293
43
    if (fill1->alloc_time > fill2->alloc_time)
1294
43
        HGOTO_DONE(1);
1295
1296
    /* Check the fill time for the fill values */
1297
0
    if (fill1->fill_time < fill2->fill_time)
1298
0
        HGOTO_DONE(-1);
1299
0
    if (fill1->fill_time > fill2->fill_time)
1300
0
        HGOTO_DONE(1);
1301
1302
52
done:
1303
52
    FUNC_LEAVE_NOAPI(ret_value)
1304
0
} /* end H5P_fill_value_cmp() */
1305
1306
/*-------------------------------------------------------------------------
1307
 * Function:    H5P__dcrt_fill_value_close
1308
 *
1309
 * Purpose:     Frees memory used to store the fill value property
1310
 *
1311
 * Return:      Success:        Non-negative
1312
 *              Failure:        Negative
1313
 *
1314
 *-------------------------------------------------------------------------
1315
 */
1316
static herr_t
1317
H5P__dcrt_fill_value_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
1318
93
{
1319
93
    herr_t ret_value = SUCCEED; /* Return value */
1320
1321
93
    FUNC_ENTER_PACKAGE
1322
1323
    /* Sanity check */
1324
93
    assert(value);
1325
1326
    /* Reset the old fill value message */
1327
93
    if (H5O_msg_reset(H5O_FILL_ID, value) < 0)
1328
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release fill value message");
1329
1330
93
done:
1331
93
    FUNC_LEAVE_NOAPI(ret_value)
1332
93
} /* end H5P__dcrt_fill_value_close() */
1333
1334
/*-------------------------------------------------------------------------
1335
 * Function:    H5P__dcrt_ext_file_list_set
1336
 *
1337
 * Purpose:     Copies an external file list property when it's set for a property list
1338
 *
1339
 * Return:      Success:        Non-negative
1340
 *              Failure:        Negative
1341
 *
1342
 *-------------------------------------------------------------------------
1343
 */
1344
static herr_t
1345
H5P__dcrt_ext_file_list_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
1346
                            size_t H5_ATTR_UNUSED size, void *value)
1347
0
{
1348
0
    H5O_efl_t *efl = (H5O_efl_t *)value; /* Create local aliases for values */
1349
0
    H5O_efl_t  new_efl;
1350
0
    herr_t     ret_value = SUCCEED; /* Return value */
1351
1352
0
    FUNC_ENTER_PACKAGE
1353
1354
    /* Sanity check */
1355
0
    assert(value);
1356
1357
    /* Make copy of external file list */
1358
0
    if (NULL == H5O_msg_copy(H5O_EFL_ID, efl, &new_efl))
1359
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy external file list");
1360
1361
    /* Copy new external file list message over old one */
1362
0
    *efl = new_efl;
1363
1364
0
done:
1365
0
    FUNC_LEAVE_NOAPI(ret_value)
1366
0
} /* end H5P__dcrt_ext_file_list_set() */
1367
1368
/*-------------------------------------------------------------------------
1369
 * Function:    H5P__dcrt_ext_file_list_get
1370
 *
1371
 * Purpose:     Copies an external file list property when it's retrieved from a property list
1372
 *
1373
 * Return:      Success:        Non-negative
1374
 *              Failure:        Negative
1375
 *
1376
 *-------------------------------------------------------------------------
1377
 */
1378
static herr_t
1379
H5P__dcrt_ext_file_list_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
1380
                            size_t H5_ATTR_UNUSED size, void *value)
1381
1
{
1382
1
    H5O_efl_t *efl = (H5O_efl_t *)value; /* Create local aliases for values */
1383
1
    H5O_efl_t  new_efl;
1384
1
    herr_t     ret_value = SUCCEED; /* Return value */
1385
1386
1
    FUNC_ENTER_PACKAGE
1387
1388
    /* Sanity check */
1389
1
    assert(value);
1390
1391
    /* Make copy of external file list */
1392
1
    if (NULL == H5O_msg_copy(H5O_EFL_ID, efl, &new_efl))
1393
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy external file list");
1394
1395
    /* Copy new external file list message over old one */
1396
1
    *efl = new_efl;
1397
1398
1
done:
1399
1
    FUNC_LEAVE_NOAPI(ret_value)
1400
1
} /* end H5P__dcrt_ext_file_list_get() */
1401
1402
/*-------------------------------------------------------------------------
1403
 * Function:       H5P__dcrt_ext_file_list_enc
1404
 *
1405
 * Purpose:        Callback routine which is called whenever the efl
1406
 *                 property in the dataset creation property list is
1407
 *                 encoded.
1408
 *
1409
 * Return:     Success: Non-negative
1410
 *       Failure: Negative
1411
 *
1412
 *-------------------------------------------------------------------------
1413
 */
1414
static herr_t
1415
H5P__dcrt_ext_file_list_enc(const void *value, void **_pp, size_t *size)
1416
0
{
1417
0
    const H5O_efl_t *efl = (const H5O_efl_t *)value; /* Create local aliases for values */
1418
0
    size_t           len = 0;                        /* String length of slot name */
1419
0
    size_t           u;                              /* Local index variable */
1420
0
    uint8_t        **pp = (uint8_t **)_pp;
1421
0
    unsigned         enc_size;
1422
0
    uint64_t         enc_value;
1423
1424
0
    FUNC_ENTER_PACKAGE_NOERR
1425
1426
    /* Sanity check */
1427
0
    assert(efl);
1428
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
1429
0
    HDcompile_assert(sizeof(off_t) <= sizeof(uint64_t));
1430
0
    HDcompile_assert(sizeof(hsize_t) <= sizeof(uint64_t));
1431
0
    assert(size);
1432
1433
0
    if (NULL != *pp) {
1434
        /* Encode number of slots used */
1435
0
        enc_value = (uint64_t)efl->nused;
1436
0
        enc_size  = H5VM_limit_enc_size(enc_value);
1437
0
        assert(enc_size < 256);
1438
0
        *(*pp)++ = (uint8_t)enc_size;
1439
0
        UINT64ENCODE_VAR(*pp, enc_value, enc_size);
1440
1441
        /* Encode file list */
1442
0
        for (u = 0; u < efl->nused; u++) {
1443
            /* Calculate length of slot name and encode it */
1444
0
            len       = strlen(efl->slot[u].name) + 1;
1445
0
            enc_value = (uint64_t)len;
1446
0
            enc_size  = H5VM_limit_enc_size(enc_value);
1447
0
            assert(enc_size < 256);
1448
0
            *(*pp)++ = (uint8_t)enc_size;
1449
0
            UINT64ENCODE_VAR(*pp, enc_value, enc_size);
1450
1451
            /* Encode name */
1452
0
            H5MM_memcpy(*pp, (uint8_t *)(efl->slot[u].name), len);
1453
0
            *pp += len;
1454
1455
            /* Encode offset */
1456
0
            enc_value = (uint64_t)efl->slot[u].offset;
1457
0
            enc_size  = H5VM_limit_enc_size(enc_value);
1458
0
            assert(enc_size < 256);
1459
0
            *(*pp)++ = (uint8_t)enc_size;
1460
0
            UINT64ENCODE_VAR(*pp, enc_value, enc_size);
1461
1462
            /* encode size */
1463
0
            enc_value = (uint64_t)efl->slot[u].size;
1464
0
            enc_size  = H5VM_limit_enc_size(enc_value);
1465
0
            assert(enc_size < 256);
1466
0
            *(*pp)++ = (uint8_t)enc_size;
1467
0
            UINT64ENCODE_VAR(*pp, enc_value, enc_size);
1468
0
        } /* end for */
1469
0
    }     /* end if */
1470
1471
    /* Calculate size needed for encoding */
1472
0
    *size += (1 + H5VM_limit_enc_size((uint64_t)efl->nused));
1473
0
    for (u = 0; u < efl->nused; u++) {
1474
0
        len = strlen(efl->slot[u].name) + 1;
1475
0
        *size += (1 + H5VM_limit_enc_size((uint64_t)len));
1476
0
        *size += len;
1477
0
        *size += (1 + H5VM_limit_enc_size((uint64_t)efl->slot[u].offset));
1478
0
        *size += (1 + H5VM_limit_enc_size((uint64_t)efl->slot[u].size));
1479
0
    } /* end for */
1480
1481
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1482
0
} /* end H5P__dcrt_ext_file_list_enc() */
1483
1484
/*-------------------------------------------------------------------------
1485
 * Function:       H5P__dcrt_ext_file_list_dec
1486
 *
1487
 * Purpose:        Callback routine which is called whenever the efl
1488
 *                 property in the dataset creation property list is
1489
 *                 decoded.
1490
 *
1491
 * Return:     Success: Non-negative
1492
 *       Failure: Negative
1493
 *
1494
 *-------------------------------------------------------------------------
1495
 */
1496
static herr_t
1497
H5P__dcrt_ext_file_list_dec(const void **_pp, void *_value)
1498
0
{
1499
0
    H5O_efl_t      *efl = (H5O_efl_t *)_value; /* External file list */
1500
0
    const uint8_t **pp  = (const uint8_t **)_pp;
1501
0
    size_t          u, nused;
1502
0
    unsigned        enc_size;
1503
0
    uint64_t        enc_value;
1504
0
    herr_t          ret_value = SUCCEED; /* Return value */
1505
1506
0
    FUNC_ENTER_PACKAGE
1507
1508
    /* Sanity check */
1509
0
    assert(pp);
1510
0
    assert(*pp);
1511
0
    assert(efl);
1512
0
    HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
1513
0
    HDcompile_assert(sizeof(off_t) <= sizeof(uint64_t));
1514
0
    HDcompile_assert(sizeof(hsize_t) <= sizeof(uint64_t));
1515
1516
    /* Set property to default value */
1517
0
    *efl = H5D_def_efl_g;
1518
1519
    /* Decode number of slots used */
1520
0
    enc_size = *(*pp)++;
1521
0
    assert(enc_size < 256);
1522
0
    UINT64DECODE_VAR(*pp, enc_value, enc_size);
1523
0
    nused = (size_t)enc_value;
1524
1525
    /* Decode information for each slot */
1526
0
    for (u = 0; u < nused; u++) {
1527
0
        size_t len;
1528
0
        if (efl->nused >= efl->nalloc) {
1529
0
            size_t           na = efl->nalloc + H5O_EFL_ALLOC;
1530
0
            H5O_efl_entry_t *x  = (H5O_efl_entry_t *)H5MM_realloc(efl->slot, na * sizeof(H5O_efl_entry_t));
1531
0
            if (!x)
1532
0
                HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed");
1533
1534
0
            efl->nalloc = na;
1535
0
            efl->slot   = x;
1536
0
        } /* end if */
1537
1538
        /* Decode length of slot name */
1539
0
        enc_size = *(*pp)++;
1540
0
        assert(enc_size < 256);
1541
0
        UINT64DECODE_VAR(*pp, enc_value, enc_size);
1542
0
        len = (size_t)enc_value;
1543
1544
        /* Allocate name buffer and decode the name into it */
1545
0
        efl->slot[u].name = H5MM_xstrdup((const char *)(*pp));
1546
0
        *pp += len;
1547
1548
        /* decode offset */
1549
0
        enc_size = *(*pp)++;
1550
0
        assert(enc_size < 256);
1551
0
        UINT64DECODE_VAR(*pp, enc_value, enc_size);
1552
0
        efl->slot[u].offset = (HDoff_t)enc_value;
1553
1554
        /* decode size */
1555
0
        enc_size = *(*pp)++;
1556
0
        assert(enc_size < 256);
1557
0
        UINT64DECODE_VAR(*pp, enc_value, enc_size);
1558
0
        efl->slot[u].size = (hsize_t)enc_value;
1559
1560
0
        efl->slot[u].name_offset = 0; /*not entered into heap yet*/
1561
0
        efl->nused++;
1562
0
    } /* end for */
1563
1564
0
done:
1565
0
    FUNC_LEAVE_NOAPI(ret_value)
1566
0
} /* end H5P__dcrt_ext_file_list_dec() */
1567
1568
/*-------------------------------------------------------------------------
1569
 * Function:    H5P__dcrt_ext_file_list_del
1570
 *
1571
 * Purpose:     Frees memory used to store the efl property
1572
 *
1573
 * Return:      Success:        Non-negative
1574
 *              Failure:        Negative
1575
 *
1576
 *-------------------------------------------------------------------------
1577
 */
1578
static herr_t
1579
H5P__dcrt_ext_file_list_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
1580
                            size_t H5_ATTR_UNUSED size, void *value)
1581
0
{
1582
0
    herr_t ret_value = SUCCEED; /* Return value */
1583
1584
0
    FUNC_ENTER_PACKAGE
1585
1586
    /* Sanity check */
1587
0
    assert(value);
1588
1589
    /* Reset the old efl message */
1590
0
    if (H5O_msg_reset(H5O_EFL_ID, value) < 0)
1591
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release external file list message");
1592
1593
0
done:
1594
0
    FUNC_LEAVE_NOAPI(ret_value)
1595
0
} /* end H5P__dcrt_ext_file_list_del() */
1596
1597
/*--------------------------------------------------------------------------
1598
 * Function:    H5P__dcrt_ext_file_list_copy
1599
 *
1600
 * Purpose:     Copy the efl property
1601
 *
1602
 * Return:      Success:        Non-negative
1603
 *              Failure:        Negative
1604
 *
1605
 *--------------------------------------------------------------------------
1606
 */
1607
static herr_t
1608
H5P__dcrt_ext_file_list_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
1609
92
{
1610
92
    H5O_efl_t *efl = (H5O_efl_t *)value; /* Create local aliases for values */
1611
92
    H5O_efl_t  new_efl;
1612
92
    herr_t     ret_value = SUCCEED;
1613
1614
92
    FUNC_ENTER_PACKAGE
1615
1616
92
    assert(efl);
1617
1618
    /* Make copy of efl message */
1619
92
    if (NULL == H5O_msg_copy(H5O_EFL_ID, efl, &new_efl))
1620
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy external file list");
1621
1622
    /* Set new efl message directly into property list */
1623
92
    *efl = new_efl;
1624
1625
92
done:
1626
92
    FUNC_LEAVE_NOAPI(ret_value)
1627
92
} /* end H5P__dcrt_ext_file_list_copy() */
1628
1629
/*-------------------------------------------------------------------------
1630
 * Function:       H5P__dcrt_ext_file_list_cmp
1631
 *
1632
 * Purpose:        Callback routine which is called whenever the external file
1633
 *                 list property in the dataset creation property list is
1634
 *                 compared.
1635
 *
1636
 * Return:         positive if VALUE1 is greater than VALUE2, negative if
1637
 *                      VALUE2 is greater than VALUE1 and zero if VALUE1 and
1638
 *                      VALUE2 are equal.
1639
 *
1640
 *-------------------------------------------------------------------------
1641
 */
1642
static int
1643
H5P__dcrt_ext_file_list_cmp(const void *_efl1, const void *_efl2, size_t H5_ATTR_UNUSED size)
1644
0
{
1645
0
    const H5O_efl_t *efl1 = (const H5O_efl_t *)_efl1, /* Create local aliases for values */
1646
0
        *efl2             = (const H5O_efl_t *)_efl2;
1647
0
    int    cmp_value;     /* Value from comparison */
1648
0
    herr_t ret_value = 0; /* Return value */
1649
1650
0
    FUNC_ENTER_PACKAGE_NOERR
1651
1652
    /* Sanity check */
1653
0
    assert(efl1);
1654
0
    assert(efl2);
1655
0
    assert(size == sizeof(H5O_efl_t));
1656
1657
    /* Check the number of allocated efl entries */
1658
0
    if (efl1->nalloc < efl2->nalloc)
1659
0
        HGOTO_DONE(-1);
1660
0
    if (efl1->nalloc > efl2->nalloc)
1661
0
        HGOTO_DONE(1);
1662
1663
    /* Check the number of used efl entries */
1664
0
    if (efl1->nused < efl2->nused)
1665
0
        HGOTO_DONE(-1);
1666
0
    if (efl1->nused > efl2->nused)
1667
0
        HGOTO_DONE(1);
1668
1669
    /* Check the efl entry information */
1670
0
    if (efl1->slot == NULL && efl2->slot != NULL)
1671
0
        HGOTO_DONE(-1);
1672
0
    if (efl1->slot != NULL && efl2->slot == NULL)
1673
0
        HGOTO_DONE(1);
1674
0
    if (efl1->slot != NULL && efl1->nused > 0) {
1675
0
        size_t u; /* Local index variable */
1676
1677
        /* Loop through all entries, comparing them */
1678
0
        for (u = 0; u < efl1->nused; u++) {
1679
            /* Check the name offset of the efl entry */
1680
0
            if (efl1->slot[u].name_offset < efl2->slot[u].name_offset)
1681
0
                HGOTO_DONE(-1);
1682
0
            if (efl1->slot[u].name_offset > efl2->slot[u].name_offset)
1683
0
                HGOTO_DONE(1);
1684
1685
            /* Check the name of the efl entry */
1686
0
            if (efl1->slot[u].name == NULL && efl2->slot[u].name != NULL)
1687
0
                HGOTO_DONE(-1);
1688
0
            if (efl1->slot[u].name != NULL && efl2->slot[u].name == NULL)
1689
0
                HGOTO_DONE(1);
1690
0
            if (efl1->slot[u].name != NULL)
1691
0
                if ((cmp_value = strcmp(efl1->slot[u].name, efl2->slot[u].name)) != 0)
1692
0
                    HGOTO_DONE(cmp_value);
1693
1694
            /* Check the file offset of the efl entry */
1695
0
            if (efl1->slot[u].offset < efl2->slot[u].offset)
1696
0
                HGOTO_DONE(-1);
1697
0
            if (efl1->slot[u].offset > efl2->slot[u].offset)
1698
0
                HGOTO_DONE(1);
1699
1700
            /* Check the file size of the efl entry */
1701
0
            if (efl1->slot[u].size < efl2->slot[u].size)
1702
0
                HGOTO_DONE(-1);
1703
0
            if (efl1->slot[u].size > efl2->slot[u].size)
1704
0
                HGOTO_DONE(1);
1705
0
        } /* end for */
1706
0
    }     /* end if */
1707
1708
0
done:
1709
0
    FUNC_LEAVE_NOAPI(ret_value)
1710
0
} /* end H5P__dcrt_ext_file_list_cmp() */
1711
1712
/*-------------------------------------------------------------------------
1713
 * Function:    H5P__dcrt_ext_file_list_close
1714
 *
1715
 * Purpose:     Frees memory used to store the efl property
1716
 *
1717
 * Return:      Success:        Non-negative
1718
 *              Failure:        Negative
1719
 *
1720
 *-------------------------------------------------------------------------
1721
 */
1722
static herr_t
1723
H5P__dcrt_ext_file_list_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
1724
93
{
1725
93
    herr_t ret_value = SUCCEED; /* Return value */
1726
1727
93
    FUNC_ENTER_PACKAGE
1728
1729
    /* Sanity check */
1730
93
    assert(value);
1731
1732
    /* Reset the old efl message */
1733
93
    if (H5O_msg_reset(H5O_EFL_ID, value) < 0)
1734
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release external file list message");
1735
1736
93
done:
1737
93
    FUNC_LEAVE_NOAPI(ret_value)
1738
93
} /* end H5P__dcrt_ext_file_list_close() */
1739
1740
/*-------------------------------------------------------------------------
1741
 * Function:  H5P__set_layout
1742
 *
1743
 * Purpose:   Sets the layout of raw data in the file.
1744
 *
1745
 * Return:    Non-negative on success/Negative on failure
1746
 *
1747
 *-------------------------------------------------------------------------
1748
 */
1749
static herr_t
1750
H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout)
1751
0
{
1752
0
    unsigned alloc_time_state;    /* State of allocation time property */
1753
0
    herr_t   ret_value = SUCCEED; /* return value */
1754
1755
0
    FUNC_ENTER_PACKAGE
1756
1757
    /* Get the allocation time state */
1758
0
    if (H5P_get(plist, H5D_CRT_ALLOC_TIME_STATE_NAME, &alloc_time_state) < 0)
1759
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get space allocation time state");
1760
1761
    /* If we still have the "default" allocation time, change it according to the new layout */
1762
0
    if (alloc_time_state) {
1763
0
        H5O_fill_t fill; /* Fill value */
1764
1765
        /* Get current fill value info */
1766
0
        if (H5P_peek(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
1767
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
1768
1769
        /* Set the default based on layout */
1770
0
        switch (layout->type) {
1771
0
            case H5D_COMPACT:
1772
0
                fill.alloc_time = H5D_ALLOC_TIME_EARLY;
1773
0
                break;
1774
1775
0
            case H5D_CONTIGUOUS:
1776
0
                fill.alloc_time = H5D_ALLOC_TIME_LATE;
1777
0
                break;
1778
1779
0
            case H5D_CHUNKED:
1780
0
            case H5D_VIRTUAL:
1781
0
                fill.alloc_time = H5D_ALLOC_TIME_INCR;
1782
0
                break;
1783
1784
0
            case H5D_LAYOUT_ERROR:
1785
0
            case H5D_NLAYOUTS:
1786
0
            default:
1787
0
                HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unknown layout type");
1788
0
        } /* end switch */
1789
1790
        /* Set updated fill value info */
1791
0
        if (H5P_poke(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
1792
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set space allocation time");
1793
0
    } /* end if */
1794
1795
    /* Set layout value */
1796
0
    if (H5P_set(plist, H5D_CRT_LAYOUT_NAME, layout) < 0)
1797
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set layout");
1798
1799
0
done:
1800
0
    FUNC_LEAVE_NOAPI(ret_value)
1801
0
} /* end H5P__set_layout() */
1802
1803
/*-------------------------------------------------------------------------
1804
 * Function:  H5Pset_layout
1805
 *
1806
 * Purpose: Sets the layout of raw data in the file.
1807
 *
1808
 * Return:  Non-negative on success/Negative on failure
1809
 *
1810
 *-------------------------------------------------------------------------
1811
 */
1812
herr_t
1813
H5Pset_layout(hid_t plist_id, H5D_layout_t layout_type)
1814
0
{
1815
0
    H5P_genplist_t     *plist;               /* Property list pointer */
1816
0
    const H5O_layout_t *layout;              /* Pointer to default layout information for type specified */
1817
0
    herr_t              ret_value = SUCCEED; /* Return value */
1818
1819
0
    FUNC_ENTER_API(FAIL)
1820
1821
    /* Check arguments */
1822
0
    if (layout_type < 0 || layout_type >= H5D_NLAYOUTS)
1823
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "raw data layout method is not valid");
1824
1825
    /* Get the plist structure */
1826
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
1827
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1828
1829
    /* Get pointer to correct default layout */
1830
0
    switch (layout_type) {
1831
0
        case H5D_COMPACT:
1832
0
            layout = &H5D_def_layout_compact_g;
1833
0
            break;
1834
1835
0
        case H5D_CONTIGUOUS:
1836
0
            layout = &H5D_def_layout_contig_g;
1837
0
            break;
1838
1839
0
        case H5D_CHUNKED:
1840
0
            layout = &H5D_def_layout_chunk_g;
1841
0
            break;
1842
1843
0
        case H5D_VIRTUAL:
1844
0
            layout = &H5D_def_layout_virtual_g;
1845
0
            break;
1846
1847
0
        case H5D_LAYOUT_ERROR:
1848
0
        case H5D_NLAYOUTS:
1849
0
        default:
1850
0
            HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unknown layout type");
1851
0
    } /* end switch */
1852
1853
    /* Set value */
1854
0
    if (H5P__set_layout(plist, layout) < 0)
1855
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set layout");
1856
1857
0
done:
1858
0
    FUNC_LEAVE_API(ret_value)
1859
0
} /* end H5Pset_layout() */
1860
1861
/*-------------------------------------------------------------------------
1862
 * Function:  H5Pget_layout
1863
 *
1864
 * Purpose: Retrieves layout type of a dataset creation property list.
1865
 *
1866
 * Return:  Success:  The layout type
1867
 *
1868
 *    Failure:  H5D_LAYOUT_ERROR (negative)
1869
 *
1870
 *-------------------------------------------------------------------------
1871
 */
1872
H5D_layout_t
1873
H5Pget_layout(hid_t plist_id)
1874
0
{
1875
0
    H5P_genplist_t *plist;     /* Property list pointer */
1876
0
    H5O_layout_t    layout;    /* Layout property */
1877
0
    H5D_layout_t    ret_value; /* Return value */
1878
1879
0
    FUNC_ENTER_API(H5D_LAYOUT_ERROR)
1880
1881
    /* Get the plist structure */
1882
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
1883
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, H5D_LAYOUT_ERROR, "can't find object for ID");
1884
1885
    /* Peek at layout property */
1886
0
    if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
1887
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5D_LAYOUT_ERROR, "can't get layout");
1888
1889
    /* Set return value */
1890
0
    ret_value = layout.type;
1891
1892
0
done:
1893
0
    FUNC_LEAVE_API(ret_value)
1894
0
} /* ed H5Pget_layout() */
1895
1896
/*-------------------------------------------------------------------------
1897
 * Function:  H5Pset_chunk
1898
 *
1899
 * Purpose: Sets the number of dimensions and the size of each chunk to
1900
 *    the values specified.  The dimensionality of the chunk should
1901
 *    match the dimensionality of the dataspace.
1902
 *
1903
 *    As a side effect, the layout method is changed to
1904
 *    H5D_CHUNKED.
1905
 *
1906
 * Return:  Non-negative on success/Negative on failure
1907
 *
1908
 *-------------------------------------------------------------------------
1909
 */
1910
herr_t
1911
H5Pset_chunk(hid_t plist_id, int ndims, const hsize_t dim[/*ndims*/])
1912
0
{
1913
0
    H5P_genplist_t *plist;               /* Property list pointer */
1914
0
    H5O_layout_t    chunk_layout;        /* Layout information for setting chunk info */
1915
0
    uint64_t        chunk_nelmts;        /* Number of elements in chunk */
1916
0
    unsigned        u;                   /* Local index variable */
1917
0
    herr_t          ret_value = SUCCEED; /* Return value */
1918
1919
0
    FUNC_ENTER_API(FAIL)
1920
1921
    /* Check arguments */
1922
0
    if (ndims <= 0)
1923
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "chunk dimensionality must be positive");
1924
0
    if (ndims > H5S_MAX_RANK)
1925
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "chunk dimensionality is too large");
1926
0
    if (!dim)
1927
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no chunk dimensions specified");
1928
1929
    /* Verify & initialize property's chunk dims */
1930
0
    H5MM_memcpy(&chunk_layout, &H5D_def_layout_chunk_g, sizeof(H5D_def_layout_chunk_g));
1931
0
    memset(&chunk_layout.u.chunk.dim, 0, sizeof(chunk_layout.u.chunk.dim));
1932
0
    chunk_nelmts = 1;
1933
0
    for (u = 0; u < (unsigned)ndims; u++) {
1934
0
        if (dim[u] == 0)
1935
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "all chunk dimensions must be positive");
1936
0
        if (dim[u] != (dim[u] & 0xffffffff))
1937
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "all chunk dimensions must be less than 2^32");
1938
0
        chunk_nelmts *= dim[u];
1939
0
        if (chunk_nelmts > (uint64_t)0xffffffff)
1940
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "number of elements in chunk must be < 4GB");
1941
0
        chunk_layout.u.chunk.dim[u] = (uint32_t)dim[u]; /* Store user's chunk dimensions */
1942
0
    }                                                   /* end for */
1943
1944
    /* Get the plist structure */
1945
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
1946
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1947
1948
    /* Set chunk information in property list */
1949
0
    chunk_layout.u.chunk.ndims = (unsigned)ndims;
1950
0
    if (H5P__set_layout(plist, &chunk_layout) < 0)
1951
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout");
1952
1953
0
done:
1954
0
    FUNC_LEAVE_API(ret_value)
1955
0
} /* end H5Pset_chunk() */
1956
1957
/*-------------------------------------------------------------------------
1958
 * Function:  H5Pget_chunk
1959
 *
1960
 * Purpose: Retrieves the chunk size of chunked layout.  The chunk
1961
 *    dimensionality is returned and the chunk size in each
1962
 *    dimension is returned through the DIM argument.  At most
1963
 *    MAX_NDIMS elements of DIM will be initialized.
1964
 *
1965
 * Return:  Success:  Positive Chunk dimensionality.
1966
 *
1967
 *    Failure:  Negative
1968
 *
1969
 *-------------------------------------------------------------------------
1970
 */
1971
int
1972
H5Pget_chunk(hid_t plist_id, int max_ndims, hsize_t dim[] /*out*/)
1973
0
{
1974
0
    H5P_genplist_t *plist;     /* Property list pointer */
1975
0
    H5O_layout_t    layout;    /* Layout information */
1976
0
    int             ret_value; /* Return value */
1977
1978
0
    FUNC_ENTER_API(FAIL)
1979
1980
    /* Get the plist structure */
1981
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
1982
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
1983
1984
    /* Peek at the layout property */
1985
0
    if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
1986
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout");
1987
0
    if (H5D_CHUNKED != layout.type)
1988
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a chunked storage layout");
1989
1990
0
    if (dim) {
1991
0
        unsigned u; /* Local index variable */
1992
1993
        /* Get the dimension sizes */
1994
0
        for (u = 0; u < layout.u.chunk.ndims && u < (unsigned)max_ndims; u++)
1995
0
            dim[u] = layout.u.chunk.dim[u];
1996
0
    } /* end if */
1997
1998
    /* Set the return value */
1999
0
    ret_value = (int)layout.u.chunk.ndims;
2000
2001
0
done:
2002
0
    FUNC_LEAVE_API(ret_value)
2003
0
} /* end H5Pget_chunk() */
2004
2005
/*-------------------------------------------------------------------------
2006
 * Function:    H5Pset_virtual
2007
 *
2008
 * Purpose:     Maps elements of the virtual dataset described by the
2009
 *              virtual dataspace identifier vspace_id to the elements of
2010
 *              the source dataset described by the source dataset
2011
 *              dataspace identifier src_space_id.  The source dataset is
2012
 *              identified by the name of the file where it is located,
2013
 *              src_file_name, and the name of the dataset, src_dset_name.
2014
 *
2015
 *              As a side effect, the layout method is changed to
2016
 *              H5D_VIRTUAL.
2017
 *
2018
 * Return:      Non-negative on success/Negative on failure
2019
 *
2020
 *-------------------------------------------------------------------------
2021
 */
2022
herr_t
2023
H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, const char *src_dset_name,
2024
               hid_t src_space_id)
2025
0
{
2026
0
    H5P_genplist_t            *plist = NULL;               /* Property list pointer */
2027
0
    H5O_layout_t               virtual_layout;             /* Layout information for setting virtual info */
2028
0
    H5S_t                     *vspace;                     /* Virtual dataset space selection */
2029
0
    H5S_t                     *src_space;                  /* Source dataset space selection */
2030
0
    H5O_storage_virtual_ent_t *old_list         = NULL;    /* List pointer previously on property list */
2031
0
    H5O_storage_virtual_ent_t *ent              = NULL;    /* Convenience pointer to new VDS entry */
2032
0
    bool                       retrieved_layout = false;   /* Whether the layout has been retrieved */
2033
0
    bool                       free_list        = false;   /* Whether to free the list of virtual entries */
2034
0
    herr_t                     ret_value        = SUCCEED; /* Return value */
2035
2036
0
    FUNC_ENTER_API(FAIL)
2037
2038
    /* Check arguments */
2039
0
    if (!src_file_name)
2040
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "source file name not provided");
2041
0
    if (!src_dset_name)
2042
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "source dataset name not provided");
2043
0
    if (NULL == (vspace = (H5S_t *)H5I_object_verify(vspace_id, H5I_DATASPACE)))
2044
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dataspace");
2045
0
    if (NULL == (src_space = (H5S_t *)H5I_object_verify(src_space_id, H5I_DATASPACE)))
2046
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a dataspace");
2047
2048
    /* Check selections for validity */
2049
0
    if (H5D_virtual_check_mapping_pre(vspace, src_space, H5O_VIRTUAL_STATUS_USER) < 0)
2050
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "invalid mapping selections");
2051
2052
    /* Get the plist structure */
2053
0
    if (NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
2054
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2055
2056
    /* Get the current layout */
2057
0
    if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &virtual_layout) < 0)
2058
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get layout");
2059
0
    retrieved_layout = true;
2060
2061
    /* If the layout was not already virtual, Start with default virtual layout.
2062
     * Otherwise, add the mapping to the current list. */
2063
0
    if (virtual_layout.type == H5D_VIRTUAL)
2064
        /* Save old list pointer for error recovery */
2065
0
        old_list = virtual_layout.storage.u.virt.list;
2066
0
    else {
2067
        /* Reset the old layout */
2068
0
        if (H5O_msg_reset(H5O_LAYOUT_ID, &virtual_layout) < 0)
2069
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTRESET, FAIL, "can't release layout message");
2070
2071
        /* Copy the default virtual layout */
2072
0
        H5MM_memcpy(&virtual_layout, &H5D_def_layout_virtual_g, sizeof(H5D_def_layout_virtual_g));
2073
2074
        /* Sanity check */
2075
0
        assert(virtual_layout.storage.u.virt.list_nalloc == 0);
2076
0
    } /* end else */
2077
2078
    /* Expand list if necessary */
2079
0
    if (virtual_layout.storage.u.virt.list_nused == virtual_layout.storage.u.virt.list_nalloc) {
2080
0
        H5O_storage_virtual_ent_t *x; /* Pointer to the new list */
2081
0
        size_t new_alloc = MAX(H5D_VIRTUAL_DEF_LIST_SIZE, virtual_layout.storage.u.virt.list_nalloc * 2);
2082
2083
        /* Expand size of entry list */
2084
0
        if (NULL == (x = (H5O_storage_virtual_ent_t *)H5MM_realloc(
2085
0
                         virtual_layout.storage.u.virt.list, new_alloc * sizeof(H5O_storage_virtual_ent_t))))
2086
0
            HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't reallocate virtual dataset mapping list");
2087
0
        virtual_layout.storage.u.virt.list        = x;
2088
0
        virtual_layout.storage.u.virt.list_nalloc = new_alloc;
2089
0
    } /* end if */
2090
2091
    /* Add virtual dataset mapping entry */
2092
0
    ent = &virtual_layout.storage.u.virt.list[virtual_layout.storage.u.virt.list_nused];
2093
0
    memset(ent, 0, sizeof(H5O_storage_virtual_ent_t)); /* Clear before starting to set up */
2094
0
    if (NULL == (ent->source_dset.virtual_select = H5S_copy(vspace, false, true)))
2095
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection");
2096
0
    if (NULL == (ent->source_file_name = H5MM_xstrdup(src_file_name)))
2097
0
        HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name");
2098
0
    if (NULL == (ent->source_dset_name = H5MM_xstrdup(src_dset_name)))
2099
0
        HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name");
2100
0
    if (NULL == (ent->source_select = H5S_copy(src_space, false, true)))
2101
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection");
2102
0
    if (H5D_virtual_parse_source_name(ent->source_file_name, &ent->parsed_source_file_name,
2103
0
                                      &ent->psfn_static_strlen, &ent->psfn_nsubs) < 0)
2104
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source file name");
2105
0
    if (H5D_virtual_parse_source_name(ent->source_dset_name, &ent->parsed_source_dset_name,
2106
0
                                      &ent->psdn_static_strlen, &ent->psdn_nsubs) < 0)
2107
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source dataset name");
2108
0
    if ((ent->psfn_nsubs == 0) && (ent->psdn_nsubs == 0)) {
2109
0
        if (ent->parsed_source_file_name)
2110
0
            ent->source_dset.file_name = ent->parsed_source_file_name->name_segment;
2111
0
        else
2112
0
            ent->source_dset.file_name = ent->source_file_name;
2113
0
        if (ent->parsed_source_dset_name)
2114
0
            ent->source_dset.dset_name = ent->parsed_source_dset_name->name_segment;
2115
0
        else
2116
0
            ent->source_dset.dset_name = ent->source_dset_name;
2117
0
    } /* end if */
2118
0
    ent->unlim_dim_source  = H5S_get_select_unlim_dim(src_space);
2119
0
    ent->unlim_dim_virtual = H5S_get_select_unlim_dim(vspace);
2120
0
    if (ent->unlim_dim_virtual < 0) {
2121
0
        ent->source_dset.clipped_source_select  = ent->source_select;
2122
0
        ent->source_dset.clipped_virtual_select = ent->source_dset.virtual_select;
2123
0
    } /* end if */
2124
0
    ent->unlim_extent_source  = HSIZE_UNDEF;
2125
0
    ent->unlim_extent_virtual = HSIZE_UNDEF;
2126
0
    ent->clip_size_source     = HSIZE_UNDEF;
2127
0
    ent->clip_size_virtual    = HSIZE_UNDEF;
2128
0
    ent->source_space_status  = H5O_VIRTUAL_STATUS_USER;
2129
0
    ent->virtual_space_status = H5O_VIRTUAL_STATUS_USER;
2130
2131
    /* Check entry for validity */
2132
0
    if (H5D_virtual_check_mapping_post(ent) < 0)
2133
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid mapping entry");
2134
2135
    /* Update min_dims */
2136
0
    if (H5D_virtual_update_min_dims(&virtual_layout, virtual_layout.storage.u.virt.list_nused) < 0)
2137
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to update virtual dataset minimum dimensions");
2138
2139
    /* Finish adding entry */
2140
0
    virtual_layout.storage.u.virt.list_nused++;
2141
2142
0
done:
2143
    /* Set VDS layout information in property list */
2144
    /* (Even on failure, so there's not a mangled layout struct in the list) */
2145
0
    if (retrieved_layout) {
2146
0
        if (H5P_poke(plist, H5D_CRT_LAYOUT_NAME, &virtual_layout) < 0) {
2147
0
            HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout");
2148
0
            if (old_list != virtual_layout.storage.u.virt.list)
2149
0
                free_list = true;
2150
0
        } /* end if */
2151
0
    }     /* end if */
2152
2153
    /* Check if the entry has been partly allocated but not added to the
2154
     * property list or not included in list_nused */
2155
0
    if (ret_value < 0) {
2156
        /* Free incomplete entry if present */
2157
0
        if (ent) {
2158
0
            ent->source_file_name = (char *)H5MM_xfree(ent->source_file_name);
2159
0
            ent->source_dset_name = (char *)H5MM_xfree(ent->source_dset_name);
2160
0
            if (ent->source_dset.virtual_select && H5S_close(ent->source_dset.virtual_select) < 0)
2161
0
                HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release virtual selection");
2162
0
            ent->source_dset.virtual_select = NULL;
2163
0
            if (ent->source_select && H5S_close(ent->source_select) < 0)
2164
0
                HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection");
2165
0
            ent->source_select = NULL;
2166
0
            H5D_virtual_free_parsed_name(ent->parsed_source_file_name);
2167
0
            ent->parsed_source_file_name = NULL;
2168
0
            H5D_virtual_free_parsed_name(ent->parsed_source_dset_name);
2169
0
            ent->parsed_source_dset_name = NULL;
2170
0
        } /* end if */
2171
2172
        /* Free list if necessary */
2173
0
        if (free_list)
2174
0
            virtual_layout.storage.u.virt.list =
2175
0
                (H5O_storage_virtual_ent_t *)H5MM_xfree(virtual_layout.storage.u.virt.list);
2176
0
    } /* end if */
2177
2178
0
    FUNC_LEAVE_API(ret_value)
2179
0
} /* end H5Pset_virtual() */
2180
2181
/*-------------------------------------------------------------------------
2182
 * Function:    H5Pget_virtual_count
2183
 *
2184
 * Purpose:     Gets the number of mappings for the virtual dataset that
2185
 *              has a creation property list specified by the dcpl_id
2186
 *              parameter.
2187
 *
2188
 * Return:      Non-negative on success/Negative on failure
2189
 *
2190
 *-------------------------------------------------------------------------
2191
 */
2192
herr_t
2193
H5Pget_virtual_count(hid_t dcpl_id, size_t *count /*out*/)
2194
0
{
2195
0
    H5P_genplist_t *plist;               /* Property list pointer */
2196
0
    H5O_layout_t    layout;              /* Layout information */
2197
0
    herr_t          ret_value = SUCCEED; /* Return value */
2198
2199
0
    FUNC_ENTER_API(FAIL)
2200
2201
0
    if (count) {
2202
        /* Get the plist structure */
2203
0
        if (NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
2204
0
            HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2205
2206
        /* Retrieve the layout property */
2207
0
        if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
2208
0
            HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout");
2209
0
        if (H5D_VIRTUAL != layout.type)
2210
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout");
2211
2212
        /* Return the number of mappings  */
2213
0
        *count = layout.storage.u.virt.list_nused;
2214
0
    } /* end if */
2215
2216
0
done:
2217
0
    FUNC_LEAVE_API(ret_value)
2218
0
} /* end H5Pget_virtual_count() */
2219
2220
/*-------------------------------------------------------------------------
2221
 * Function:    H5Pget_virtual_vspace
2222
 *
2223
 * Purpose:     Takes the dataset creation property list for the virtual
2224
 *              dataset, dcpl_id, and the mapping index, index, and
2225
 *              returns a dataspace identifier for the selection within
2226
 *              the virtual dataset used in the mapping.
2227
 *
2228
 * Return:      Returns a dataspace identifier if successful; otherwise
2229
 *              returns a negative value.
2230
 *
2231
 *-------------------------------------------------------------------------
2232
 */
2233
hid_t
2234
H5Pget_virtual_vspace(hid_t dcpl_id, size_t idx)
2235
0
{
2236
0
    H5P_genplist_t *plist;        /* Property list pointer */
2237
0
    H5O_layout_t    layout;       /* Layout information */
2238
0
    H5S_t          *space = NULL; /* Dataspace pointer */
2239
0
    hid_t           ret_value;    /* Return value */
2240
2241
0
    FUNC_ENTER_API(FAIL)
2242
2243
    /* Get the plist structure */
2244
0
    if (NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
2245
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2246
2247
    /* Retrieve the layout property */
2248
0
    if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
2249
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout");
2250
0
    if (H5D_VIRTUAL != layout.type)
2251
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout");
2252
2253
    /* Get the virtual space */
2254
0
    if (idx >= layout.storage.u.virt.list_nused)
2255
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)");
2256
0
    assert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc);
2257
0
    if (NULL == (space = H5S_copy(layout.storage.u.virt.list[idx].source_dset.virtual_select, false, true)))
2258
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection");
2259
2260
    /* Register ID */
2261
0
    if ((ret_value = H5I_register(H5I_DATASPACE, space, true)) < 0)
2262
0
        HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, FAIL, "unable to register dataspace");
2263
2264
0
done:
2265
    /* Free space on failure */
2266
0
    if ((ret_value < 0) && space)
2267
0
        if (H5S_close(space) < 0)
2268
0
            HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection");
2269
2270
0
    FUNC_LEAVE_API(ret_value)
2271
0
} /* end H5Pget_virtual_vspace() */
2272
2273
/*-------------------------------------------------------------------------
2274
 * Function:    H5Pget_virtual_srcspace
2275
 *
2276
 * Purpose:     Takes the dataset creation property list for the virtual
2277
 *              dataset, dcpl_id, and the mapping index, index, and
2278
 *              returns a dataspace identifier for the selection within
2279
 *              the source dataset used in the mapping.
2280
 *
2281
 * Return:      Returns a dataspace identifier if successful; otherwise
2282
 *              returns a negative value.
2283
 *
2284
 *-------------------------------------------------------------------------
2285
 */
2286
hid_t
2287
H5Pget_virtual_srcspace(hid_t dcpl_id, size_t idx)
2288
0
{
2289
0
    H5P_genplist_t *plist;            /* Property list pointer */
2290
0
    H5O_layout_t    layout;           /* Layout information */
2291
0
    H5S_t          *space     = NULL; /* Dataspace pointer */
2292
0
    hid_t           ret_value = FAIL; /* Return value */
2293
2294
0
    FUNC_ENTER_API(FAIL)
2295
2296
    /* Get the plist structure */
2297
0
    if (NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
2298
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2299
2300
    /* Retrieve the layout property */
2301
0
    if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
2302
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout");
2303
0
    if (H5D_VIRTUAL != layout.type)
2304
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout");
2305
2306
    /* Check index */
2307
0
    if (idx >= layout.storage.u.virt.list_nused)
2308
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)");
2309
0
    assert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc);
2310
2311
    /* Attempt to open source dataset and patch extent if extent status is not
2312
     * H5O_VIRTUAL_STATUS_CORRECT?  -NAF */
2313
    /* If source space status is H5O_VIRTUAL_STATUS_INVALID, patch with bounds
2314
     * of selection */
2315
0
    if ((H5O_VIRTUAL_STATUS_INVALID == layout.storage.u.virt.list[idx].source_space_status) &&
2316
0
        (layout.storage.u.virt.list[idx].unlim_dim_source < 0)) {
2317
0
        hsize_t bounds_start[H5S_MAX_RANK];
2318
0
        hsize_t bounds_end[H5S_MAX_RANK];
2319
0
        int     rank;
2320
0
        int     i;
2321
2322
        /* Get rank of source space */
2323
0
        if ((rank = H5S_GET_EXTENT_NDIMS(layout.storage.u.virt.list[idx].source_select)) < 0)
2324
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get source space rank");
2325
2326
        /* Get bounds of selection */
2327
0
        if (H5S_SELECT_BOUNDS(layout.storage.u.virt.list[idx].source_select, bounds_start, bounds_end) < 0)
2328
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get selection bounds");
2329
2330
        /* Adjust bounds to extent */
2331
0
        for (i = 0; i < rank; i++)
2332
0
            bounds_end[i]++;
2333
2334
        /* Set extent */
2335
0
        if (H5S_set_extent_simple(layout.storage.u.virt.list[idx].source_select, (unsigned)rank, bounds_end,
2336
0
                                  NULL) < 0)
2337
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set source space extent");
2338
2339
        /* Update source space status */
2340
0
        layout.storage.u.virt.list[idx].source_space_status = H5O_VIRTUAL_STATUS_SEL_BOUNDS;
2341
0
    } /* end if */
2342
2343
    /* Get the source space */
2344
0
    if (NULL == (space = H5S_copy(layout.storage.u.virt.list[idx].source_select, false, true)))
2345
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection");
2346
2347
    /* Register ID */
2348
0
    if ((ret_value = H5I_register(H5I_DATASPACE, space, true)) < 0)
2349
0
        HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, FAIL, "unable to register dataspace");
2350
2351
0
done:
2352
    /* Free space on failure */
2353
0
    if ((ret_value < 0) && space)
2354
0
        if (H5S_close(space) < 0)
2355
0
            HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection");
2356
2357
0
    FUNC_LEAVE_API(ret_value)
2358
0
} /* end H5Pget_virtual_srcspace() */
2359
2360
/*-------------------------------------------------------------------------
2361
 * Function:    H5Pget_virtual_filename
2362
 *
2363
 * Purpose:     Takes the dataset creation property list for the virtual
2364
 *              dataset, dcpl_id, and the mapping index, index, and
2365
 *              retrieves a name of a file for a source dataset used in
2366
 *              the mapping.
2367
 *
2368
 *              Up to size characters of the filename are returned in
2369
 *              name; additional characters, if any, are not returned to
2370
 *              the user application.
2371
 *
2372
 *              If the length of the filename, which determines the
2373
 *              required value of size, is unknown, a preliminary call to
2374
 *              H5Pget_virtual_filename with 'name' set to NULL and 'size'
2375
 *              set to zero can be made. The return value of this call will
2376
 *              be the size in bytes of the filename.  That value, plus 1
2377
 *              for a NULL terminator, is then assigned to size for a
2378
 *              second H5Pget_virtual_filename call, which will retrieve
2379
 *              the actual filename.
2380
 *
2381
 * Return:      Returns the length of the name if successful, otherwise
2382
 *              returns a negative value.
2383
 *
2384
 *-------------------------------------------------------------------------
2385
 */
2386
ssize_t
2387
H5Pget_virtual_filename(hid_t dcpl_id, size_t idx, char *name /*out*/, size_t size)
2388
0
{
2389
0
    H5P_genplist_t *plist;     /* Property list pointer */
2390
0
    H5O_layout_t    layout;    /* Layout information */
2391
0
    ssize_t         ret_value; /* Return value */
2392
2393
0
    FUNC_ENTER_API(FAIL)
2394
2395
    /* Get the plist structure */
2396
0
    if (NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
2397
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2398
2399
    /* Retrieve the layout property */
2400
0
    if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
2401
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout");
2402
0
    if (H5D_VIRTUAL != layout.type)
2403
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout");
2404
2405
    /* Get the virtual filename */
2406
0
    if (idx >= layout.storage.u.virt.list_nused)
2407
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)");
2408
0
    assert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc);
2409
0
    assert(layout.storage.u.virt.list[idx].source_file_name);
2410
0
    if (name && (size > 0))
2411
0
        (void)strncpy(name, layout.storage.u.virt.list[idx].source_file_name, size);
2412
0
    ret_value = (ssize_t)strlen(layout.storage.u.virt.list[idx].source_file_name);
2413
2414
0
done:
2415
0
    FUNC_LEAVE_API(ret_value)
2416
0
} /* end H5Pget_virtual_filename() */
2417
2418
/*-------------------------------------------------------------------------
2419
 * Function:    H5Pget_virtual_dsetname
2420
 *
2421
 * Purpose:     Takes the dataset creation property list for the virtual
2422
 *              dataset, dcpl_id, and the mapping index, index, and
2423
 *              retrieves the name of a source dataset used in the mapping.
2424
 *
2425
 *              Up to size characters of the name are returned in name;
2426
 *              additional characters, if any, are not returned to the
2427
 *              user application.
2428
 *
2429
 *              If the length of the dataset name, which determines the
2430
 *              required value of size, is unknown, a preliminary call to
2431
 *              H5Pget_virtual_dsetname with 'name' set to NULL and 'size'
2432
 *              set to zero can be made.  The return value of this call will
2433
 *              be the size in bytes of the dataset name.  That value, plus 1
2434
 *              for a NULL terminator, is then assigned to size for a
2435
 *              second H5Pget_virtual_dsetname call, which will retrieve
2436
 *              the actual dataset name.
2437
 *
2438
 * Return:      Returns the length of the name if successful, otherwise
2439
 *              returns a negative value.
2440
 *
2441
 *-------------------------------------------------------------------------
2442
 */
2443
ssize_t
2444
H5Pget_virtual_dsetname(hid_t dcpl_id, size_t idx, char *name /*out*/, size_t size)
2445
0
{
2446
0
    H5P_genplist_t *plist;     /* Property list pointer */
2447
0
    H5O_layout_t    layout;    /* Layout information */
2448
0
    ssize_t         ret_value; /* Return value */
2449
2450
0
    FUNC_ENTER_API(FAIL)
2451
2452
    /* Get the plist structure */
2453
0
    if (NULL == (plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE)))
2454
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2455
2456
    /* Retrieve the layout property */
2457
0
    if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
2458
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout");
2459
0
    if (H5D_VIRTUAL != layout.type)
2460
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a virtual storage layout");
2461
2462
    /* Get the virtual filename */
2463
0
    if (idx >= layout.storage.u.virt.list_nused)
2464
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)");
2465
0
    assert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc);
2466
0
    assert(layout.storage.u.virt.list[idx].source_dset_name);
2467
0
    if (name && (size > 0))
2468
0
        (void)strncpy(name, layout.storage.u.virt.list[idx].source_dset_name, size);
2469
0
    ret_value = (ssize_t)strlen(layout.storage.u.virt.list[idx].source_dset_name);
2470
2471
0
done:
2472
0
    FUNC_LEAVE_API(ret_value)
2473
0
} /* end H5Pget_virtual_dsetname() */
2474
2475
/*-------------------------------------------------------------------------
2476
 * Function:    H5Pset_chunk_opts
2477
 *
2478
 * Purpose:     Sets the options related to chunked storage for a dataset.
2479
 *              The storage must already be set to chunked.
2480
 *
2481
 * Return:      Non-negative on success/Negative on failure
2482
 *
2483
 *-------------------------------------------------------------------------
2484
 */
2485
herr_t
2486
H5Pset_chunk_opts(hid_t plist_id, unsigned options)
2487
0
{
2488
0
    H5P_genplist_t *plist;                  /* Property list pointer */
2489
0
    H5O_layout_t    layout;                 /* Layout information for setting chunk info */
2490
0
    uint8_t         layout_flags = 0;       /* "options" translated into layout message flags format */
2491
0
    herr_t          ret_value    = SUCCEED; /* Return value */
2492
2493
0
    FUNC_ENTER_API(FAIL)
2494
2495
    /* Check arguments */
2496
0
    if (options & ~(H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS))
2497
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "unknown chunk options");
2498
2499
    /* Get the plist structure */
2500
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
2501
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2502
2503
    /* Retrieve the layout property */
2504
0
    if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
2505
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout");
2506
0
    if (H5D_CHUNKED != layout.type)
2507
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a chunked storage layout");
2508
2509
    /* Translate options into flags that can be used with the layout message */
2510
0
    if (options & H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS)
2511
0
        layout_flags |= H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS;
2512
2513
    /* Update the layout message, including the version (if necessary) */
2514
    /* This probably isn't the right way to do this, and should be changed once
2515
     * this branch gets the "real" way to set the layout version */
2516
0
    layout.u.chunk.flags = layout_flags;
2517
0
    if (layout.version < H5O_LAYOUT_VERSION_4)
2518
0
        layout.version = H5O_LAYOUT_VERSION_4;
2519
2520
    /* Set layout value */
2521
0
    if (H5P_poke(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
2522
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set layout");
2523
2524
0
done:
2525
0
    FUNC_LEAVE_API(ret_value)
2526
0
} /* end H5Pset_chunk_opts() */
2527
2528
/*-------------------------------------------------------------------------
2529
 * Function:    H5Pget_chunk_opts
2530
 *
2531
 * Purpose:     Gets the options related to chunked storage for a dataset.
2532
 *
2533
 * Return:      Non-negative on success/Negative on failure
2534
 *
2535
 *-------------------------------------------------------------------------
2536
 */
2537
herr_t
2538
H5Pget_chunk_opts(hid_t plist_id, unsigned *options /*out*/)
2539
0
{
2540
0
    H5P_genplist_t *plist;               /* Property list pointer */
2541
0
    H5O_layout_t    layout;              /* Layout information for setting chunk info */
2542
0
    herr_t          ret_value = SUCCEED; /* Return value */
2543
2544
0
    FUNC_ENTER_API(FAIL)
2545
2546
    /* Get the plist structure */
2547
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
2548
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2549
2550
    /* Retrieve the layout property */
2551
0
    if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
2552
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't get layout");
2553
0
    if (H5D_CHUNKED != layout.type)
2554
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a chunked storage layout");
2555
2556
0
    if (options) {
2557
        /* Translate options from flags that can be used with the layout message
2558
         * to those known to the public */
2559
0
        *options = 0;
2560
0
        if (layout.u.chunk.flags & H5O_LAYOUT_CHUNK_DONT_FILTER_PARTIAL_BOUND_CHUNKS)
2561
0
            *options |= H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS;
2562
0
    } /* end if */
2563
2564
0
done:
2565
0
    FUNC_LEAVE_API(ret_value)
2566
0
} /* end H5Pget_chunk_opts() */
2567
2568
/*-------------------------------------------------------------------------
2569
 * Function:  H5Pset_external
2570
 *
2571
 * Purpose: Adds an external file to the list of external files. PLIST_ID
2572
 *    should be an object ID for a dataset creation property list.
2573
 *    NAME is the name of an external file, OFFSET is the location
2574
 *    where the data starts in that file, and SIZE is the number of
2575
 *    bytes reserved in the file for the data.
2576
 *
2577
 *    If a dataset is split across multiple files then the files
2578
 *    should be defined in order. The total size of the dataset is
2579
 *    the sum of the SIZE arguments for all the external files.  If
2580
 *    the total size is larger than the size of a dataset then the
2581
 *    dataset can be extended (provided the dataspace also allows
2582
 *    the extending).
2583
 *
2584
 * Return:  Non-negative on success/Negative on failure
2585
 *
2586
 *-------------------------------------------------------------------------
2587
 */
2588
herr_t
2589
H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size)
2590
0
{
2591
0
    size_t          idx;
2592
0
    hsize_t         total, tmp;
2593
0
    H5O_efl_t       efl;
2594
0
    H5P_genplist_t *plist;               /* Property list pointer */
2595
0
    herr_t          ret_value = SUCCEED; /* Return value */
2596
2597
0
    FUNC_ENTER_API(FAIL)
2598
2599
    /* Check arguments */
2600
0
    if (!name || !*name)
2601
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given");
2602
0
    if (offset < 0)
2603
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "negative external file offset");
2604
2605
    /* Get the plist structure */
2606
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
2607
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2608
2609
0
    if (H5P_peek(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
2610
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list");
2611
0
    if (efl.nused > 0 && H5O_EFL_UNLIMITED == efl.slot[efl.nused - 1].size)
2612
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "previous file size is unlimited");
2613
2614
0
    if (H5O_EFL_UNLIMITED != size) {
2615
0
        for (idx = 0, total = size; idx < efl.nused; idx++, total = tmp) {
2616
0
            tmp = total + efl.slot[idx].size;
2617
0
            if (tmp <= total)
2618
0
                HGOTO_ERROR(H5E_EFL, H5E_OVERFLOW, FAIL, "total external data size overflowed");
2619
0
        } /* end for */
2620
0
    }     /* end if */
2621
2622
    /* Add to the list */
2623
0
    if (efl.nused >= efl.nalloc) {
2624
0
        size_t           na = efl.nalloc + H5O_EFL_ALLOC;
2625
0
        H5O_efl_entry_t *x  = (H5O_efl_entry_t *)H5MM_realloc(efl.slot, na * sizeof(H5O_efl_entry_t));
2626
2627
0
        if (!x)
2628
0
            HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "memory allocation failed");
2629
0
        efl.nalloc = na;
2630
0
        efl.slot   = x;
2631
0
    } /* end if */
2632
0
    idx                       = efl.nused;
2633
0
    efl.slot[idx].name_offset = 0; /*not entered into heap yet*/
2634
0
    efl.slot[idx].name        = H5MM_xstrdup(name);
2635
0
    efl.slot[idx].offset      = offset;
2636
0
    efl.slot[idx].size        = size;
2637
0
    efl.nused++;
2638
2639
0
    if (H5P_poke(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
2640
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set external file list");
2641
2642
0
done:
2643
0
    FUNC_LEAVE_API(ret_value)
2644
0
} /* end H5Pset_external() */
2645
2646
/*-------------------------------------------------------------------------
2647
 * Function:  H5Pget_external_count
2648
 *
2649
 * Purpose: Returns the number of external files for this dataset.
2650
 *
2651
 * Return:  Success:  Number of external files
2652
 *
2653
 *    Failure:  Negative
2654
 *
2655
 *-------------------------------------------------------------------------
2656
 */
2657
int
2658
H5Pget_external_count(hid_t plist_id)
2659
0
{
2660
0
    H5O_efl_t       efl;
2661
0
    H5P_genplist_t *plist;     /* Property list pointer */
2662
0
    int             ret_value; /* return value */
2663
2664
0
    FUNC_ENTER_API(FAIL)
2665
2666
    /* Get the plist structure */
2667
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
2668
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2669
2670
    /* Get value */
2671
0
    if (H5P_peek(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
2672
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list");
2673
2674
    /* Set return value */
2675
0
    ret_value = (int)efl.nused;
2676
2677
0
done:
2678
0
    FUNC_LEAVE_API(ret_value)
2679
0
} /* end H5Pget_external_count() */
2680
2681
/*-------------------------------------------------------------------------
2682
 * Function:  H5Pget_external
2683
 *
2684
 * Purpose: Returns information about an external file.  External files
2685
 *    are numbered from zero to N-1 where N is the value returned
2686
 *    by H5Pget_external_count().  At most NAME_SIZE characters are
2687
 *    copied into the NAME array.  If the external file name is
2688
 *    longer than NAME_SIZE with the null terminator, then the
2689
 *    return value is not null terminated (similar to strncpy()).
2690
 *
2691
 *    If NAME_SIZE is zero or NAME is the null pointer then the
2692
 *    external file name is not returned.  If OFFSET or SIZE are
2693
 *    null pointers then the corresponding information is not
2694
 *    returned.
2695
 *
2696
 * See Also:  H5Pset_external()
2697
 *
2698
 * Return:  Non-negative on success/Negative on failure
2699
 *
2700
 *-------------------------------------------------------------------------
2701
 */
2702
herr_t
2703
H5Pget_external(hid_t plist_id, unsigned idx, size_t name_size, char *name /*out*/, off_t *offset /*out*/,
2704
                hsize_t *size /*out*/)
2705
0
{
2706
0
    H5O_efl_t       efl;
2707
0
    H5P_genplist_t *plist;               /* Property list pointer */
2708
0
    herr_t          ret_value = SUCCEED; /* return value */
2709
2710
0
    FUNC_ENTER_API(FAIL)
2711
2712
    /* Get the plist structure */
2713
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
2714
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2715
2716
    /* Get value */
2717
0
    if (H5P_peek(plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
2718
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external file list");
2719
2720
0
    if (idx >= efl.nused)
2721
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "external file index is out of range");
2722
2723
    /* Return values */
2724
0
    if (name_size > 0 && name)
2725
0
        strncpy(name, efl.slot[idx].name, name_size);
2726
    /* XXX: Badness!
2727
     *
2728
     * The offset parameter is of type off_t and the offset field of H5O_efl_entry_t
2729
     * is HDoff_t which is a different type on Windows (off_t is a 32-bit long,
2730
     * HDoff_t is __int64, a 64-bit type).
2731
     *
2732
     * In a future API reboot, we'll either want to make this parameter a haddr_t
2733
     * or define a 64-bit HDF5-specific offset type that is platform-independent.
2734
     */
2735
0
    if (offset)
2736
0
        *offset = (off_t)efl.slot[idx].offset;
2737
0
    if (size)
2738
0
        *size = efl.slot[idx].size;
2739
2740
0
done:
2741
0
    FUNC_LEAVE_API(ret_value)
2742
0
} /* end H5Pget_external() */
2743
2744
/*-------------------------------------------------------------------------
2745
 * Function:  H5Pset_szip
2746
 *
2747
 * Purpose: Sets the compression method for a permanent or transient
2748
 *    filter pipeline (depending on whether PLIST_ID is a dataset
2749
 *    creation or transfer property list) to H5Z_FILTER_SZIP
2750
 *    Szip is a special compression package that is said to be good
2751
 *              for scientific data.
2752
 *
2753
 * Return:  Non-negative on success/Negative on failure
2754
 *
2755
 *-------------------------------------------------------------------------
2756
 */
2757
herr_t
2758
H5Pset_szip(hid_t plist_id, unsigned options_mask, unsigned pixels_per_block)
2759
0
{
2760
0
    H5O_pline_t     pline;
2761
0
    H5P_genplist_t *plist;        /* Property list pointer */
2762
0
    unsigned        cd_values[2]; /* Filter parameters */
2763
0
    unsigned int    config_flags;
2764
0
    herr_t          ret_value = SUCCEED; /* Return value */
2765
2766
0
    FUNC_ENTER_API(FAIL)
2767
2768
0
    if (H5Z_get_filter_info(H5Z_FILTER_SZIP, &config_flags) < 0)
2769
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't get filter info");
2770
2771
0
    if (!(config_flags & H5Z_FILTER_CONFIG_ENCODE_ENABLED))
2772
0
        HGOTO_ERROR(H5E_PLINE, H5E_NOENCODER, FAIL, "Filter present but encoding is disabled.");
2773
2774
    /* Check arguments */
2775
0
    if ((pixels_per_block % 2) == 1)
2776
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "pixels_per_block is not even");
2777
0
    if (pixels_per_block > H5_SZIP_MAX_PIXELS_PER_BLOCK)
2778
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "pixels_per_block is too large");
2779
2780
    /* Get the plist structure */
2781
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
2782
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2783
2784
    /* Always set K13 compression (and un-set CHIP compression) */
2785
0
    options_mask &= (unsigned)(~H5_SZIP_CHIP_OPTION_MASK);
2786
0
    options_mask |= H5_SZIP_ALLOW_K13_OPTION_MASK;
2787
2788
    /* Always set "raw" (no szip header) flag for data */
2789
0
    options_mask |= H5_SZIP_RAW_OPTION_MASK;
2790
2791
    /* Mask off the LSB and MSB options, if they were given */
2792
    /* (The HDF5 library sets them internally, as needed) */
2793
0
    options_mask &= (unsigned)(~(H5_SZIP_LSB_OPTION_MASK | H5_SZIP_MSB_OPTION_MASK));
2794
2795
    /* Set the parameters for the filter */
2796
0
    cd_values[0] = options_mask;
2797
0
    cd_values[1] = pixels_per_block;
2798
2799
    /* Add the filter */
2800
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
2801
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
2802
0
    if (H5Z_append(&pline, H5Z_FILTER_SZIP, H5Z_FLAG_OPTIONAL, (size_t)2, cd_values) < 0)
2803
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add szip filter to pipeline");
2804
0
    if (H5P_poke(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
2805
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline");
2806
2807
0
done:
2808
0
    FUNC_LEAVE_API(ret_value)
2809
0
} /* end H5Pset_szip() */
2810
2811
/*-------------------------------------------------------------------------
2812
 * Function:  H5Pset_shuffle
2813
 *
2814
 * Purpose: Sets the shuffling method for a permanent
2815
 *    filter to H5Z_FILTER_SHUFFLE
2816
 *    and bytes of the datatype of the array to be shuffled
2817
 *
2818
 * Return:  Non-negative on success/Negative on failure
2819
 *
2820
 *-------------------------------------------------------------------------
2821
 */
2822
herr_t
2823
H5Pset_shuffle(hid_t plist_id)
2824
0
{
2825
0
    H5O_pline_t     pline;
2826
0
    H5P_genplist_t *plist;               /* Property list pointer */
2827
0
    herr_t          ret_value = SUCCEED; /* return value */
2828
2829
0
    FUNC_ENTER_API(FAIL)
2830
2831
    /* Check arguments */
2832
0
    if (true != H5P_isa_class(plist_id, H5P_DATASET_CREATE))
2833
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
2834
2835
    /* Get the plist structure */
2836
0
    if (NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id)))
2837
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2838
2839
    /* Add the filter */
2840
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
2841
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
2842
0
    if (H5Z_append(&pline, H5Z_FILTER_SHUFFLE, H5Z_FLAG_OPTIONAL, (size_t)0, NULL) < 0)
2843
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to shuffle the data");
2844
0
    if (H5P_poke(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
2845
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline");
2846
2847
0
done:
2848
0
    FUNC_LEAVE_API(ret_value)
2849
0
} /* end H5Pset_shuffle() */
2850
2851
/*-------------------------------------------------------------------------
2852
 * Function:    H5Pset_nbit
2853
 *
2854
 * Purpose:     Sets nbit filter for a dataset creation property list
2855
 *
2856
 * Return:      Non-negative on success/Negative on failure
2857
 *
2858
 *-------------------------------------------------------------------------
2859
 */
2860
herr_t
2861
H5Pset_nbit(hid_t plist_id)
2862
0
{
2863
0
    H5O_pline_t     pline;
2864
0
    H5P_genplist_t *plist;               /* Property list pointer */
2865
0
    herr_t          ret_value = SUCCEED; /* return value */
2866
2867
0
    FUNC_ENTER_API(FAIL)
2868
2869
    /* Check arguments */
2870
0
    if (true != H5P_isa_class(plist_id, H5P_DATASET_CREATE))
2871
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
2872
2873
    /* Get the plist structure */
2874
0
    if (NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id)))
2875
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2876
2877
    /* Add the nbit filter */
2878
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
2879
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
2880
0
    if (H5Z_append(&pline, H5Z_FILTER_NBIT, H5Z_FLAG_OPTIONAL, (size_t)0, NULL) < 0)
2881
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add nbit filter to pipeline");
2882
0
    if (H5P_poke(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
2883
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline");
2884
2885
0
done:
2886
0
    FUNC_LEAVE_API(ret_value)
2887
0
} /* end H5Pset_nbit() */
2888
2889
/*-------------------------------------------------------------------------
2890
 * Function:    H5Pset_scaleoffset
2891
 *
2892
 * Purpose:     Sets scaleoffset filter for a dataset creation property list
2893
 *              and user-supplied parameters
2894
 *
2895
 * Parameters:  scale_factor:
2896
                              for integer datatype,
2897
                              this parameter will be
2898
                              minimum-bits, if this value is set to 0,
2899
                              scaleoffset filter will calculate the minimum-bits.
2900
2901
                              For floating-point datatype,
2902
                              For variable-minimum-bits method, this will be
2903
                              the decimal precision of the filter,
2904
                              For fixed-minimum-bits method, this will be
2905
                              the minimum-bit of the filter.
2906
                scale_type:   0 for floating-point variable-minimum-bits,
2907
                              1 for floating-point fixed-minimum-bits,
2908
                              other values, for integer datatype
2909
2910
 * Return:      Non-negative on success/Negative on failure
2911
 *
2912
 *-------------------------------------------------------------------------
2913
 */
2914
herr_t
2915
H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_factor)
2916
0
{
2917
0
    H5O_pline_t     pline;
2918
0
    H5P_genplist_t *plist;               /* Property list pointer */
2919
0
    unsigned        cd_values[2];        /* Filter parameters */
2920
0
    herr_t          ret_value = SUCCEED; /* return value */
2921
2922
0
    FUNC_ENTER_API(FAIL)
2923
2924
    /* Check arguments */
2925
0
    if (true != H5P_isa_class(plist_id, H5P_DATASET_CREATE))
2926
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
2927
2928
0
    if (scale_factor < 0)
2929
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "scale factor must be >= 0");
2930
0
    if (scale_type != H5Z_SO_FLOAT_DSCALE && scale_type != H5Z_SO_FLOAT_ESCALE && scale_type != H5Z_SO_INT)
2931
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid scale type");
2932
2933
    /* Get the plist structure */
2934
0
    if (NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id)))
2935
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2936
2937
    /* Set parameters for the filter
2938
     * scale_type = 0:     floating-point type, filter uses variable-minimum-bits method,
2939
     *                     scale_factor is decimal scale factor
2940
     * scale_type = 1:     floating-point type, filter uses fixed-minimum-bits method,
2941
     *                     scale_factor is the fixed minimum number of bits
2942
     * scale type = other: integer type, scale_factor is minimum number of bits
2943
     *                     if scale_factor = 0, then filter calculates minimum number of bits
2944
     */
2945
0
    cd_values[0] = scale_type;
2946
0
    cd_values[1] = (unsigned)scale_factor;
2947
2948
    /* Add the scaleoffset filter */
2949
0
    if (H5P_peek(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
2950
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline");
2951
0
    if (H5Z_append(&pline, H5Z_FILTER_SCALEOFFSET, H5Z_FLAG_OPTIONAL, (size_t)2, cd_values) < 0)
2952
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add scaleoffset filter to pipeline");
2953
0
    if (H5P_poke(plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
2954
0
        HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline");
2955
2956
0
done:
2957
0
    FUNC_LEAVE_API(ret_value)
2958
0
} /* end H5Pset_scaleoffset() */
2959
2960
/*-------------------------------------------------------------------------
2961
 * Function:  H5Pset_fill_value
2962
 *
2963
 * Purpose: Set the fill value for a dataset creation property list. The
2964
 *    VALUE is interpreted as being of type TYPE, which need not
2965
 *    be the same type as the dataset but the library must be able
2966
 *    to convert VALUE to the dataset type when the dataset is
2967
 *    created.  If VALUE is NULL, it will be interpreted as
2968
 *    undefining fill value.
2969
 *
2970
 * Return:  Non-negative on success/Negative on failure
2971
 *
2972
 *-------------------------------------------------------------------------
2973
 */
2974
herr_t
2975
H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value)
2976
0
{
2977
0
    H5P_genplist_t *plist;               /* Property list pointer */
2978
0
    H5O_fill_t      fill;                /* Fill value to modify */
2979
0
    herr_t          ret_value = SUCCEED; /* Return value */
2980
2981
0
    FUNC_ENTER_API(FAIL)
2982
2983
    /* Get the plist structure */
2984
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
2985
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
2986
2987
    /* Get the current fill value */
2988
0
    if (H5P_peek(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
2989
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
2990
2991
    /* Release the dynamic fill value components */
2992
0
    H5O_fill_reset_dyn(&fill);
2993
2994
0
    if (value) {
2995
0
        H5T_t      *type;  /* Datatype for fill value */
2996
0
        H5T_path_t *tpath; /* Conversion information */
2997
2998
        /* Retrieve pointer to datatype */
2999
0
        if (NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
3000
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
3001
3002
        /* Set the fill value */
3003
0
        if (NULL == (fill.type = H5T_copy(type, H5T_COPY_TRANSIENT)))
3004
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "can't copy datatype");
3005
0
        fill.size = (ssize_t)H5T_get_size(type);
3006
0
        if (NULL == (fill.buf = H5MM_malloc((size_t)fill.size)))
3007
0
            HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for fill value");
3008
0
        H5MM_memcpy(fill.buf, value, (size_t)fill.size);
3009
3010
        /* Set up type conversion function */
3011
0
        if (NULL == (tpath = H5T_path_find(type, type)))
3012
0
            HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL,
3013
0
                        "unable to convert between src and dest data types");
3014
3015
        /* If necessary, convert fill value datatypes (which copies VL components, etc.) */
3016
0
        if (!H5T_path_noop(tpath)) {
3017
0
            uint8_t *bkg_buf = NULL; /* Background conversion buffer */
3018
3019
            /* Allocate a background buffer */
3020
0
            if (H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, (size_t)fill.size)))
3021
0
                HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
3022
3023
            /* Convert the fill value */
3024
0
            if (H5T_convert(tpath, type, type, (size_t)1, (size_t)0, (size_t)0, fill.buf, bkg_buf) < 0) {
3025
0
                if (bkg_buf)
3026
0
                    bkg_buf = H5FL_BLK_FREE(type_conv, bkg_buf);
3027
0
                HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "datatype conversion failed");
3028
0
            } /* end if */
3029
3030
            /* Release the background buffer */
3031
0
            if (bkg_buf)
3032
0
                bkg_buf = H5FL_BLK_FREE(type_conv, bkg_buf);
3033
0
        } /* end if */
3034
0
    }     /* end if */
3035
0
    else
3036
0
        fill.size = (-1);
3037
3038
    /* Update fill value in property list */
3039
0
    if (H5P_poke(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
3040
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set fill value");
3041
3042
0
done:
3043
0
    FUNC_LEAVE_API(ret_value)
3044
0
} /* end H5Pset_fill_value() */
3045
3046
/*-------------------------------------------------------------------------
3047
 * Function:  H5P_get_fill_value
3048
 *
3049
 * Purpose: Queries the fill value property of a dataset creation
3050
 *    property list.  The fill value is returned through the VALUE
3051
 *    pointer and the memory is allocated by the caller.  The fill
3052
 *    value will be converted from its current datatype to the
3053
 *    specified TYPE.
3054
 *
3055
 * Return:  Non-negative on success/Negative on failure
3056
 *
3057
 *-------------------------------------------------------------------------
3058
 */
3059
herr_t
3060
H5P_get_fill_value(H5P_genplist_t *plist, const H5T_t *type, void *value /*out*/)
3061
0
{
3062
0
    H5O_fill_t  fill;                /* Fill value to retrieve */
3063
0
    H5T_path_t *tpath;               /*type conversion info */
3064
0
    void       *buf       = NULL;    /*conversion buffer  */
3065
0
    void       *bkg       = NULL;    /*conversion buffer  */
3066
0
    H5T_t      *src_type  = NULL;    /*source datatype      */
3067
0
    H5T_t      *tmp_type  = NULL;    /*temporary datatype   */
3068
0
    herr_t      ret_value = SUCCEED; /* Return value */
3069
3070
0
    FUNC_ENTER_NOAPI(FAIL)
3071
3072
    /*
3073
     * If no fill value is defined then return an error.  We can't even
3074
     * return zero because we don't know the datatype of the dataset and
3075
     * datatype conversion might not have resulted in zero.  If fill value
3076
     * is undefined, also return error.
3077
     */
3078
0
    if (H5P_peek(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
3079
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
3080
0
    if (fill.size == -1)
3081
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "fill value is undefined");
3082
3083
    /* Check for "default" fill value */
3084
0
    if (fill.size == 0) {
3085
0
        memset(value, 0, H5T_get_size(type));
3086
0
        HGOTO_DONE(SUCCEED);
3087
0
    } /* end if */
3088
3089
    /*
3090
     * Can we convert between the source and destination datatypes?
3091
     */
3092
0
    if (NULL == (tpath = H5T_path_find(fill.type, type)))
3093
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to convert between src and dst datatypes");
3094
3095
0
    src_type = fill.type;
3096
0
    if (H5T_detect_class(src_type, H5T_VLEN, false) > 0 ||
3097
0
        H5T_detect_class(src_type, H5T_REFERENCE, false) > 0) {
3098
0
        if (NULL == (tmp_type = H5T_copy(src_type, H5T_COPY_TRANSIENT)))
3099
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy fill value datatype");
3100
0
        src_type = tmp_type;
3101
0
    }
3102
3103
    /*
3104
     * Data type conversions are always done in place, so we need a buffer
3105
     * other than the fill value buffer that is large enough for both source
3106
     * and destination.  The app-supplied buffer might do okay.
3107
     */
3108
0
    if (H5T_get_size(type) >= H5T_get_size(fill.type)) {
3109
0
        buf = value;
3110
0
        if (H5T_path_bkg(tpath) && NULL == (bkg = H5MM_calloc(H5T_get_size(type))))
3111
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for type conversion");
3112
0
    } /* end if */
3113
0
    else {
3114
0
        if (NULL == (buf = H5MM_calloc(H5T_get_size(fill.type))))
3115
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for type conversion");
3116
0
        if (H5T_path_bkg(tpath) && NULL == (bkg = H5MM_calloc(H5T_get_size(fill.type))))
3117
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "memory allocation failed for type conversion");
3118
0
    } /* end else */
3119
0
    H5MM_memcpy(buf, fill.buf, H5T_get_size(fill.type));
3120
3121
    /* Do the conversion */
3122
0
    if (H5T_convert(tpath, src_type, type, (size_t)1, (size_t)0, (size_t)0, buf, bkg) < 0)
3123
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "datatype conversion failed");
3124
0
    if (buf != value)
3125
0
        H5MM_memcpy(value, buf, H5T_get_size(type));
3126
3127
0
done:
3128
0
    if (buf != value)
3129
0
        H5MM_xfree(buf);
3130
0
    if (bkg != value)
3131
0
        H5MM_xfree(bkg);
3132
0
    if (tmp_type && H5T_close(tmp_type) < 0)
3133
0
        HDONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "unable to close temporary datatype");
3134
3135
0
    FUNC_LEAVE_NOAPI(ret_value)
3136
0
} /* end H5P_get_fill_value() */
3137
3138
/*-------------------------------------------------------------------------
3139
 * Function:  H5Pget_fill_value
3140
 *
3141
 * Purpose: Queries the fill value property of a dataset creation
3142
 *    property list.  The fill value is returned through the VALUE
3143
 *    pointer and the memory is allocated by the caller.  The fill
3144
 *    value will be converted from its current datatype to the
3145
 *    specified TYPE.
3146
 *
3147
 * Return:  Non-negative on success/Negative on failure
3148
 *
3149
 *-------------------------------------------------------------------------
3150
 */
3151
herr_t
3152
H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value /*out*/)
3153
0
{
3154
0
    H5P_genplist_t *plist;               /* Property list pointer */
3155
0
    H5T_t          *type;                /* Datatype    */
3156
0
    herr_t          ret_value = SUCCEED; /* Return value */
3157
3158
0
    FUNC_ENTER_API(FAIL)
3159
3160
    /* Check arguments */
3161
0
    if (NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
3162
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
3163
0
    if (!value)
3164
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no fill value output buffer");
3165
3166
    /* Get the plist structure */
3167
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
3168
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
3169
3170
    /* Get the fill value */
3171
0
    if (H5P_get_fill_value(plist, type, value) < 0)
3172
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
3173
3174
0
done:
3175
0
    FUNC_LEAVE_API(ret_value)
3176
0
} /* end H5Pget_fill_value() */
3177
3178
/*-------------------------------------------------------------------------
3179
 * Function:    H5P_is_fill_value_defined
3180
 *
3181
 * Purpose: Check if fill value is defined.  Internal version of function
3182
 *
3183
 * Return:  Non-negative on success/Negative on failure
3184
 *
3185
 *-------------------------------------------------------------------------
3186
 */
3187
herr_t
3188
H5P_is_fill_value_defined(const H5O_fill_t *fill, H5D_fill_value_t *status)
3189
0
{
3190
0
    herr_t ret_value = SUCCEED;
3191
3192
0
    FUNC_ENTER_NOAPI(FAIL)
3193
3194
0
    assert(fill);
3195
0
    assert(status);
3196
3197
    /* Check if the fill value was "unset" */
3198
0
    if (fill->size == -1 && !fill->buf)
3199
0
        *status = H5D_FILL_VALUE_UNDEFINED;
3200
    /* Check if the fill value was set to the default fill value by the library */
3201
0
    else if (fill->size == 0 && !fill->buf)
3202
0
        *status = H5D_FILL_VALUE_DEFAULT;
3203
    /* Check if the fill value was set by the application */
3204
0
    else if (fill->size > 0 && fill->buf)
3205
0
        *status = H5D_FILL_VALUE_USER_DEFINED;
3206
0
    else {
3207
0
        *status = H5D_FILL_VALUE_ERROR;
3208
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "invalid combination of fill-value info");
3209
0
    } /* end else */
3210
3211
0
done:
3212
0
    FUNC_LEAVE_NOAPI(ret_value)
3213
0
} /* end H5P_is_fill_value_defined() */
3214
3215
/*-------------------------------------------------------------------------
3216
 * Function:    H5P_fill_value_defined
3217
 *
3218
 * Purpose: Check if fill value is defined.
3219
 *
3220
 * Return:  Non-negative on success/Negative on failure
3221
 *
3222
 *-------------------------------------------------------------------------
3223
 */
3224
herr_t
3225
H5P_fill_value_defined(H5P_genplist_t *plist, H5D_fill_value_t *status)
3226
0
{
3227
0
    H5O_fill_t fill; /* Fill value to query */
3228
0
    herr_t     ret_value = SUCCEED;
3229
3230
0
    FUNC_ENTER_NOAPI(FAIL)
3231
3232
0
    assert(status);
3233
3234
    /* Get the fill value struct */
3235
0
    if (H5P_peek(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
3236
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
3237
3238
    /* Get the fill-value status */
3239
0
    if (H5P_is_fill_value_defined(&fill, status) < 0)
3240
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't check fill value status");
3241
3242
0
done:
3243
0
    FUNC_LEAVE_NOAPI(ret_value)
3244
0
} /* end H5P_fill_value_defined() */
3245
3246
/*-------------------------------------------------------------------------
3247
 * Function:    H5Pfill_value_defined
3248
 *
3249
 * Purpose: Check if fill value is defined.
3250
 *
3251
 * Return:  Non-negative on success/Negative on failure
3252
 *
3253
 *-------------------------------------------------------------------------
3254
 */
3255
herr_t
3256
H5Pfill_value_defined(hid_t plist_id, H5D_fill_value_t *status)
3257
0
{
3258
0
    H5P_genplist_t *plist; /* Property list to query */
3259
0
    herr_t          ret_value = SUCCEED;
3260
3261
0
    FUNC_ENTER_API(FAIL)
3262
3263
0
    assert(status);
3264
3265
    /* Get the plist structure */
3266
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
3267
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
3268
3269
    /* Get the fill-value status */
3270
0
    if (H5P_fill_value_defined(plist, status) < 0)
3271
0
        HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "can't check fill value status");
3272
3273
0
done:
3274
0
    FUNC_LEAVE_API(ret_value)
3275
0
} /* end H5Pfill_value_defined() */
3276
3277
/*-------------------------------------------------------------------------
3278
 * Function:    H5Pset_alloc_time
3279
 *
3280
 * Purpose:     Set space allocation time for dataset during creation.
3281
 *    Valid values are H5D_ALLOC_TIME_DEFAULT, H5D_ALLOC_TIME_EARLY,
3282
 *      H5D_ALLOC_TIME_LATE, H5D_ALLOC_TIME_INCR
3283
 *
3284
 * Return:  Non-negative on success/Negative on failure
3285
 *
3286
 *-------------------------------------------------------------------------
3287
 */
3288
herr_t
3289
H5Pset_alloc_time(hid_t plist_id, H5D_alloc_time_t alloc_time)
3290
0
{
3291
0
    H5P_genplist_t *plist;               /* Property list pointer */
3292
0
    H5O_fill_t      fill;                /* Fill value property to modify */
3293
0
    unsigned        alloc_time_state;    /* State of allocation time property */
3294
0
    herr_t          ret_value = SUCCEED; /* return value    */
3295
3296
0
    FUNC_ENTER_API(FAIL)
3297
3298
    /* Check arguments */
3299
0
    if (alloc_time < H5D_ALLOC_TIME_DEFAULT || alloc_time > H5D_ALLOC_TIME_INCR)
3300
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid allocation time setting");
3301
3302
    /* Get the property list structure */
3303
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
3304
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
3305
3306
    /* Check for resetting to default for layout type */
3307
0
    if (alloc_time == H5D_ALLOC_TIME_DEFAULT) {
3308
0
        H5O_layout_t layout; /* Type of storage layout */
3309
3310
        /* Peek at the storage layout */
3311
0
        if (H5P_peek(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0)
3312
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get layout");
3313
3314
        /* Set the default based on layout */
3315
0
        switch (layout.type) {
3316
0
            case H5D_COMPACT:
3317
0
                alloc_time = H5D_ALLOC_TIME_EARLY;
3318
0
                break;
3319
3320
0
            case H5D_CONTIGUOUS:
3321
0
                alloc_time = H5D_ALLOC_TIME_LATE;
3322
0
                break;
3323
3324
0
            case H5D_CHUNKED:
3325
0
                alloc_time = H5D_ALLOC_TIME_INCR;
3326
0
                break;
3327
3328
0
            case H5D_VIRTUAL:
3329
0
                alloc_time = H5D_ALLOC_TIME_INCR;
3330
0
                break;
3331
3332
0
            case H5D_LAYOUT_ERROR:
3333
0
            case H5D_NLAYOUTS:
3334
0
            default:
3335
0
                HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unknown layout type");
3336
0
        } /* end switch */
3337
3338
        /* Reset the "state" of the allocation time property back to the "default" */
3339
0
        alloc_time_state = 1;
3340
0
    } /* end if */
3341
0
    else
3342
        /* Set the "state" of the allocation time property to indicate the user modified it */
3343
0
        alloc_time_state = 0;
3344
3345
    /* Retrieve previous fill value settings */
3346
0
    if (H5P_peek(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
3347
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
3348
3349
    /* Update property value */
3350
0
    fill.alloc_time = alloc_time;
3351
3352
    /* Set values */
3353
0
    if (H5P_poke(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
3354
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value");
3355
0
    if (H5P_set(plist, H5D_CRT_ALLOC_TIME_STATE_NAME, &alloc_time_state) < 0)
3356
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set space allocation time");
3357
3358
0
done:
3359
0
    FUNC_LEAVE_API(ret_value)
3360
0
} /* H5Pset_alloc_time() */
3361
3362
/*-------------------------------------------------------------------------
3363
 * Function:    H5Pget_alloc_time
3364
 *
3365
 * Purpose:     Get space allocation time for dataset creation.
3366
 *    Valid values are H5D_ALLOC_TIME_DEFAULT, H5D_ALLOC_TIME_EARLY,
3367
 *      H5D_ALLOC_TIME_LATE, H5D_ALLOC_TIME_INCR
3368
 *
3369
 * Return:      Non-negative on success/Negative on failure
3370
 *
3371
 *-------------------------------------------------------------------------
3372
 */
3373
herr_t
3374
H5Pget_alloc_time(hid_t plist_id, H5D_alloc_time_t *alloc_time /*out*/)
3375
0
{
3376
0
    herr_t ret_value = SUCCEED; /* return value          */
3377
3378
0
    FUNC_ENTER_API(FAIL)
3379
3380
    /* Get values */
3381
0
    if (alloc_time) {
3382
0
        H5P_genplist_t *plist; /* Property list pointer */
3383
0
        H5O_fill_t      fill;  /* Fill value property to query */
3384
3385
        /* Get the property list structure */
3386
0
        if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
3387
0
            HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
3388
3389
        /* Retrieve fill value settings */
3390
0
        if (H5P_peek(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
3391
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
3392
3393
        /* Set user's value */
3394
0
        *alloc_time = fill.alloc_time;
3395
0
    } /* end if */
3396
3397
0
done:
3398
0
    FUNC_LEAVE_API(ret_value)
3399
0
} /* end H5Pget_alloc_time() */
3400
3401
/*-------------------------------------------------------------------------
3402
 * Function:    H5Pset_fill_time
3403
 *
3404
 * Purpose: Set fill value writing time for dataset.  Valid values are
3405
 *    H5D_FILL_TIME_ALLOC and H5D_FILL_TIME_NEVER.
3406
 *
3407
 * Return:      Non-negative on success/Negative on failure
3408
 *
3409
 *-------------------------------------------------------------------------
3410
 */
3411
herr_t
3412
H5Pset_fill_time(hid_t plist_id, H5D_fill_time_t fill_time)
3413
0
{
3414
0
    H5P_genplist_t *plist;               /* Property list pointer */
3415
0
    H5O_fill_t      fill;                /* Fill value property to modify */
3416
0
    herr_t          ret_value = SUCCEED; /* return value          */
3417
3418
0
    FUNC_ENTER_API(FAIL)
3419
3420
    /* Check arguments */
3421
0
    if (fill_time < H5D_FILL_TIME_ALLOC || fill_time > H5D_FILL_TIME_IFSET)
3422
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fill time setting");
3423
3424
    /* Get the property list structure */
3425
0
    if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
3426
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
3427
3428
    /* Retrieve previous fill value settings */
3429
0
    if (H5P_peek(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
3430
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
3431
3432
    /* Update property value */
3433
0
    fill.fill_time = fill_time;
3434
3435
    /* Set values */
3436
0
    if (H5P_poke(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
3437
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value");
3438
3439
0
done:
3440
0
    FUNC_LEAVE_API(ret_value)
3441
0
} /* end H5Pset_fill_time() */
3442
3443
/*-------------------------------------------------------------------------
3444
 * Function:    H5Pget_fill_time
3445
 *
3446
 * Purpose: Get fill value writing time.  Valid values are H5D_NEVER
3447
 *    and H5D_ALLOC.
3448
 *
3449
 * Return:      Non-negative on success/Negative on failure
3450
 *
3451
 *-------------------------------------------------------------------------
3452
 */
3453
herr_t
3454
H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t *fill_time /*out*/)
3455
0
{
3456
0
    herr_t ret_value = SUCCEED; /* return value          */
3457
3458
0
    FUNC_ENTER_API(FAIL)
3459
3460
    /* Set values */
3461
0
    if (fill_time) {
3462
0
        H5P_genplist_t *plist; /* Property list pointer */
3463
0
        H5O_fill_t      fill;  /* Fill value property to query */
3464
3465
        /* Get the property list structure */
3466
0
        if (NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
3467
0
            HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
3468
3469
        /* Retrieve fill value settings */
3470
0
        if (H5P_peek(plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
3471
0
            HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value");
3472
3473
        /* Set user's value */
3474
0
        *fill_time = fill.fill_time;
3475
0
    } /* end if */
3476
3477
0
done:
3478
0
    FUNC_LEAVE_API(ret_value)
3479
0
} /* end H5Pget_fill_time() */
3480
3481
/*-----------------------------------------------------------------------------
3482
 * Function: H5Pget_dset_no_attrs_hint
3483
 *
3484
 * Purpose:
3485
 *
3486
 *     Access the flag for whether or not datasets created by the given dcpl
3487
 *     will be created with a "minimized" object header.
3488
 *
3489
 * Return:
3490
 *
3491
 *     Failure: Negative value (FAIL)
3492
 *     Success: Non-negative value (SUCCEED)
3493
 *
3494
 *-----------------------------------------------------------------------------
3495
 */
3496
herr_t
3497
H5Pget_dset_no_attrs_hint(hid_t dcpl_id, hbool_t *minimize /*out*/)
3498
0
{
3499
0
    bool            setting   = false;
3500
0
    H5P_genplist_t *plist     = NULL;
3501
0
    herr_t          ret_value = SUCCEED;
3502
3503
0
    FUNC_ENTER_API(FAIL)
3504
3505
0
    if (NULL == minimize)
3506
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "receiving pointer cannot be NULL");
3507
3508
0
    plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE);
3509
0
    if (NULL == plist)
3510
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
3511
3512
0
    if (H5P_peek(plist, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, &setting) < 0)
3513
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get dset oh minimize flag value");
3514
3515
0
    *minimize = setting;
3516
3517
0
done:
3518
0
    FUNC_LEAVE_API(ret_value)
3519
0
} /* H5Pget_dset_no_attrs_hint() */
3520
3521
/*-----------------------------------------------------------------------------
3522
 * Function: H5Pset_dset_no_attrs_hint
3523
 *
3524
 * Purpose:
3525
 *
3526
 *     Set the dcpl to minimize (or explicitly to not minimized) dataset object
3527
 *     headers upon creation.
3528
 *
3529
 * Return:
3530
 *
3531
 *     Failure: Negative value (FAIL)
3532
 *     Success: Non-negative value (SUCCEED)
3533
 *
3534
 *-----------------------------------------------------------------------------
3535
 */
3536
herr_t
3537
H5Pset_dset_no_attrs_hint(hid_t dcpl_id, hbool_t minimize)
3538
0
{
3539
0
    H5P_genplist_t *plist     = NULL;
3540
0
    bool            prev_set  = false;
3541
0
    herr_t          ret_value = SUCCEED;
3542
3543
0
    FUNC_ENTER_API(FAIL)
3544
3545
0
    plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE);
3546
0
    if (NULL == plist)
3547
0
        HGOTO_ERROR(H5E_ID, H5E_BADID, FAIL, "can't find object for ID");
3548
3549
0
    if (H5P_peek(plist, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, &prev_set) < 0)
3550
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get extant dset oh minimize flag value");
3551
3552
0
    if (H5P_poke(plist, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, &minimize) < 0)
3553
0
        HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't get dset oh minimize flag value");
3554
3555
0
done:
3556
0
    FUNC_LEAVE_API(ret_value)
3557
0
} /* H5Pset_dset_no_attrs_hint() */