Coverage Report

Created: 2025-11-24 06:13

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