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