Line | Count | Source |
1 | | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
2 | | * Copyright by The HDF Group. * |
3 | | * All rights reserved. * |
4 | | * * |
5 | | * This file is part of HDF5. The full HDF5 copyright notice, including * |
6 | | * terms governing use, modification, and redistribution, is contained in * |
7 | | * the LICENSE file, which can be found at the root of the source code * |
8 | | * distribution tree, or in https://www.hdfgroup.org/licenses. * |
9 | | * If you do not have access to either file, you may request a copy from * |
10 | | * help@hdfgroup.org. * |
11 | | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
12 | | |
13 | | /* |
14 | | * Module Info: This module contains the functionality for reference |
15 | | * datatypes in the H5T interface. |
16 | | */ |
17 | | |
18 | | #include "H5Tmodule.h" /* This source code file is part of the H5T module */ |
19 | | #define H5F_FRIEND /*suppress error about including H5Fpkg */ |
20 | | #define H5R_FRIEND /*suppress error about including H5Rpkg */ |
21 | | |
22 | | #include "H5private.h" /* Generic Functions */ |
23 | | #include "H5CXprivate.h" /* API Contexts */ |
24 | | #include "H5Eprivate.h" /* Error handling */ |
25 | | #include "H5Iprivate.h" /* IDs */ |
26 | | #include "H5Fpkg.h" /* File */ |
27 | | #include "H5MMprivate.h" /* Memory management */ |
28 | | #include "H5Rpkg.h" /* References */ |
29 | | #include "H5Tpkg.h" /* Datatypes */ |
30 | | |
31 | | #include "H5VLnative_private.h" /* Native VOL connector */ |
32 | | |
33 | | /****************/ |
34 | | /* Local Macros */ |
35 | | /****************/ |
36 | | |
37 | 2 | #define H5T_REF_MEM_SIZE (H5R_REF_BUF_SIZE) |
38 | 2 | #define H5T_REF_OBJ_MEM_SIZE (H5R_OBJ_REF_BUF_SIZE) |
39 | 2 | #define H5T_REF_DSETREG_MEM_SIZE (H5R_DSET_REG_REF_BUF_SIZE) |
40 | | |
41 | 15 | #define H5T_REF_OBJ_DISK_SIZE(f) (H5F_SIZEOF_ADDR(f)) |
42 | 1 | #define H5T_REF_DSETREG_DISK_SIZE(f) (H5HG_HEAP_ID_SIZE(f)) |
43 | | |
44 | | /* Debug */ |
45 | | // #define H5T_REF_DEBUG |
46 | | #ifdef H5T_REF_DEBUG |
47 | | #define H5T_REF_LOG_DEBUG(...) \ |
48 | | do { \ |
49 | | fprintf(stdout, " # %s(): ", __func__); \ |
50 | | fprintf(stdout, __VA_ARGS__); \ |
51 | | fprintf(stdout, "\n"); \ |
52 | | fflush(stdout); \ |
53 | | } while (0) |
54 | | #else |
55 | | #define H5T_REF_LOG_DEBUG(...) \ |
56 | 38 | do { \ |
57 | 38 | } while (0) |
58 | | #endif |
59 | | |
60 | | /******************/ |
61 | | /* Local Typedefs */ |
62 | | /******************/ |
63 | | |
64 | | /* For region compatibility support */ |
65 | | struct H5Tref_dsetreg { |
66 | | H5O_token_t token; /* Object token */ |
67 | | H5S_t *space; /* Dataspace */ |
68 | | }; |
69 | | |
70 | | /********************/ |
71 | | /* Local Prototypes */ |
72 | | /********************/ |
73 | | |
74 | | static herr_t H5T__ref_mem_isnull(const H5VL_object_t *src_file, const void *src_buf, bool *isnull); |
75 | | static herr_t H5T__ref_mem_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf); |
76 | | static size_t H5T__ref_mem_getsize(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
77 | | H5VL_object_t *dst_file, bool *dst_copy); |
78 | | static herr_t H5T__ref_mem_read(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
79 | | H5VL_object_t *dst_file, void *dst_buf, size_t dst_size); |
80 | | static herr_t H5T__ref_mem_write(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
81 | | H5R_type_t src_type, H5VL_object_t *dst_file, void *dst_buf, size_t dst_size, |
82 | | void *bg_buf); |
83 | | |
84 | | static herr_t H5T__ref_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, bool *isnull); |
85 | | static herr_t H5T__ref_disk_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf); |
86 | | static size_t H5T__ref_disk_getsize(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
87 | | H5VL_object_t *dst_file, bool *dst_copy); |
88 | | static herr_t H5T__ref_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
89 | | H5VL_object_t *dst_file, void *dst_buf, size_t dst_size); |
90 | | static herr_t H5T__ref_disk_write(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
91 | | H5R_type_t src_type, H5VL_object_t *dst_file, void *dst_buf, |
92 | | size_t dst_size, void *bg_buf); |
93 | | |
94 | | /* For compatibility */ |
95 | | static herr_t H5T__ref_obj_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, bool *isnull); |
96 | | static size_t H5T__ref_obj_disk_getsize(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
97 | | H5VL_object_t *dst_file, bool *dst_copy); |
98 | | static herr_t H5T__ref_obj_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
99 | | H5VL_object_t *dst_file, void *dst_buf, size_t dst_size); |
100 | | |
101 | | static herr_t H5T__ref_dsetreg_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, bool *isnull); |
102 | | static size_t H5T__ref_dsetreg_disk_getsize(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
103 | | H5VL_object_t *dst_file, bool *dst_copy); |
104 | | static herr_t H5T__ref_dsetreg_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
105 | | H5VL_object_t *dst_file, void *dst_buf, size_t dst_size); |
106 | | |
107 | | /*******************/ |
108 | | /* Local Variables */ |
109 | | /*******************/ |
110 | | |
111 | | /* Class for reference in memory */ |
112 | | static const H5T_ref_class_t H5T_ref_mem_g = { |
113 | | H5T__ref_mem_isnull, /* 'isnull' */ |
114 | | H5T__ref_mem_setnull, /* 'setnull' */ |
115 | | H5T__ref_mem_getsize, /* 'getsize' */ |
116 | | H5T__ref_mem_read, /* 'read' */ |
117 | | H5T__ref_mem_write /* 'write' */ |
118 | | }; |
119 | | |
120 | | static const H5T_ref_class_t H5T_ref_disk_g = { |
121 | | H5T__ref_disk_isnull, /* 'isnull' */ |
122 | | H5T__ref_disk_setnull, /* 'setnull' */ |
123 | | H5T__ref_disk_getsize, /* 'getsize' */ |
124 | | H5T__ref_disk_read, /* 'read' */ |
125 | | H5T__ref_disk_write /* 'write' */ |
126 | | }; |
127 | | |
128 | | static const H5T_ref_class_t H5T_ref_obj_disk_g = { |
129 | | H5T__ref_obj_disk_isnull, /* 'isnull' */ |
130 | | NULL, /* 'setnull' */ |
131 | | H5T__ref_obj_disk_getsize, /* 'getsize' */ |
132 | | H5T__ref_obj_disk_read, /* 'read' */ |
133 | | NULL /* 'write' */ |
134 | | }; |
135 | | |
136 | | static const H5T_ref_class_t H5T_ref_dsetreg_disk_g = { |
137 | | H5T__ref_dsetreg_disk_isnull, /* 'isnull' */ |
138 | | NULL, /* 'setnull' */ |
139 | | H5T__ref_dsetreg_disk_getsize, /* 'getsize' */ |
140 | | H5T__ref_dsetreg_disk_read, /* 'read' */ |
141 | | NULL /* 'write' */ |
142 | | }; |
143 | | |
144 | | /*------------------------------------------------------------------------- |
145 | | * Function: H5T__ref_set_loc |
146 | | * |
147 | | * Purpose: Sets the location of a reference datatype to be either on disk |
148 | | * or in memory |
149 | | * |
150 | | * Return: |
151 | | * One of two values on success: |
152 | | * true - If the location of any reference types changed |
153 | | * false - If the location of any reference types is the same |
154 | | * Negative value is returned on failure |
155 | | * |
156 | | *------------------------------------------------------------------------- |
157 | | */ |
158 | | htri_t |
159 | | H5T__ref_set_loc(H5T_t *dt, H5VL_object_t *file, H5T_loc_t loc) |
160 | 38 | { |
161 | 38 | htri_t ret_value = false; /* Indicate success, but no location change */ |
162 | | |
163 | 38 | FUNC_ENTER_PACKAGE |
164 | 38 | H5T_REF_LOG_DEBUG("loc=%d", (int)loc); |
165 | | |
166 | 38 | assert(dt); |
167 | | /* f is NULL when loc == H5T_LOC_MEMORY */ |
168 | 38 | assert(loc >= H5T_LOC_BADLOC && loc < H5T_LOC_MAXLOC); |
169 | | |
170 | | /* Only change the location if it's different */ |
171 | 38 | if (loc == dt->shared->u.atomic.u.r.loc && file == dt->shared->u.atomic.u.r.file) |
172 | 16 | HGOTO_DONE(false); |
173 | | |
174 | 22 | switch (loc) { |
175 | 6 | case H5T_LOC_MEMORY: /* Memory based reference datatype */ |
176 | | |
177 | | /* NB. We allow for the file to be non-NULL when doing |
178 | | * memory-to-memory conversion */ |
179 | | |
180 | | /* Mark this type as being stored in memory */ |
181 | 6 | dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY; |
182 | | |
183 | | /* Release owned file */ |
184 | 6 | if (dt->shared->owned_vol_obj) { |
185 | 0 | if (H5VL_free_object(dt->shared->owned_vol_obj) < 0) |
186 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCLOSEOBJ, FAIL, "unable to close owned VOL object"); |
187 | 0 | dt->shared->owned_vol_obj = NULL; |
188 | 0 | } /* end if */ |
189 | | |
190 | | /* Reset file ID (since this reference is in memory) */ |
191 | 6 | dt->shared->u.atomic.u.r.file = file; /* file is NULL */ |
192 | | |
193 | 6 | if (dt->shared->u.atomic.u.r.opaque) { |
194 | | /* Size in memory, disk size is different */ |
195 | 2 | dt->shared->size = H5T_REF_MEM_SIZE; |
196 | 2 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
197 | | |
198 | | /* Set up the function pointers to access the reference in memory */ |
199 | 2 | dt->shared->u.atomic.u.r.cls = &H5T_ref_mem_g; |
200 | 2 | } /* end if */ |
201 | 4 | else if (dt->shared->u.atomic.u.r.rtype == H5R_OBJECT1) { |
202 | | /* Size in memory, disk size is different */ |
203 | 2 | dt->shared->size = H5T_REF_OBJ_MEM_SIZE; |
204 | 2 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
205 | | |
206 | | /* Unused for now */ |
207 | 2 | dt->shared->u.atomic.u.r.cls = NULL; |
208 | 2 | } /* end else-if */ |
209 | 2 | else if (dt->shared->u.atomic.u.r.rtype == H5R_DATASET_REGION1) { |
210 | | /* Size in memory, disk size is different */ |
211 | 2 | dt->shared->size = H5T_REF_DSETREG_MEM_SIZE; |
212 | 2 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
213 | | |
214 | | /* Unused for now */ |
215 | 2 | dt->shared->u.atomic.u.r.cls = NULL; |
216 | 2 | } /* end else-if */ |
217 | 0 | else |
218 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid location"); |
219 | 6 | break; |
220 | | |
221 | 16 | case H5T_LOC_DISK: /* Disk based reference datatype */ |
222 | 16 | assert(file); |
223 | | |
224 | | /* Mark this type as being stored on disk */ |
225 | 16 | dt->shared->u.atomic.u.r.loc = H5T_LOC_DISK; |
226 | | |
227 | | /* Set file pointer (since this reference is on disk) */ |
228 | 16 | dt->shared->u.atomic.u.r.file = file; |
229 | | |
230 | | /* dt now owns a reference to file */ |
231 | 16 | if (H5T_own_vol_obj(dt, file) < 0) |
232 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "can't give ownership of VOL object"); |
233 | | |
234 | 16 | if (dt->shared->u.atomic.u.r.rtype == H5R_OBJECT1) { |
235 | 15 | H5F_t *f; |
236 | | |
237 | | #ifndef NDEBUG |
238 | | { |
239 | | bool is_native = false; /* Whether the file is using the native VOL connector */ |
240 | | |
241 | | /* Check if using native VOL connector */ |
242 | | if (H5VL_object_is_native(file, &is_native) < 0) |
243 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, |
244 | | "can't query if file uses native VOL connector"); |
245 | | |
246 | | /* Must use native VOL connector for this operation */ |
247 | | assert(is_native); |
248 | | } |
249 | | #endif /* NDEBUG */ |
250 | | |
251 | | /* Retrieve file from VOL object */ |
252 | 15 | if (NULL == (f = (H5F_t *)H5VL_object_data(file))) |
253 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
254 | | |
255 | | /* Size on disk, memory size is different */ |
256 | 15 | dt->shared->size = H5T_REF_OBJ_DISK_SIZE(f); |
257 | 15 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
258 | | |
259 | | /* Set up the function pointers to access the reference in memory */ |
260 | 15 | dt->shared->u.atomic.u.r.cls = &H5T_ref_obj_disk_g; |
261 | 15 | } /* end if */ |
262 | 1 | else if (dt->shared->u.atomic.u.r.rtype == H5R_DATASET_REGION1) { |
263 | 1 | H5F_t *f; |
264 | | |
265 | | #ifndef NDEBUG |
266 | | { |
267 | | bool is_native = false; /* Whether the file is using the native VOL connector */ |
268 | | |
269 | | /* Check if using native VOL connector */ |
270 | | if (H5VL_object_is_native(file, &is_native) < 0) |
271 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, |
272 | | "can't query if file uses native VOL connector"); |
273 | | |
274 | | /* Must use native VOL connector for this operation */ |
275 | | assert(is_native); |
276 | | } |
277 | | #endif /* NDEBUG */ |
278 | | |
279 | | /* Retrieve file from VOL object */ |
280 | 1 | if (NULL == (f = (H5F_t *)H5VL_object_data(file))) |
281 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
282 | | |
283 | | /* Size on disk, memory size is different */ |
284 | 1 | dt->shared->size = H5T_REF_DSETREG_DISK_SIZE(f); |
285 | 1 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
286 | | |
287 | | /* Set up the function pointers to access the reference in memory */ |
288 | 1 | dt->shared->u.atomic.u.r.cls = &H5T_ref_dsetreg_disk_g; |
289 | 1 | } /* end else-if */ |
290 | 0 | else { |
291 | 0 | H5VL_file_cont_info_t cont_info = {H5VL_CONTAINER_INFO_VERSION, 0, 0, 0}; |
292 | 0 | H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ |
293 | 0 | size_t ref_encode_size; |
294 | 0 | H5R_ref_priv_t fixed_ref; |
295 | | |
296 | | /* Set up VOL callback arguments */ |
297 | 0 | vol_cb_args.op_type = H5VL_FILE_GET_CONT_INFO; |
298 | 0 | vol_cb_args.args.get_cont_info.info = &cont_info; |
299 | | |
300 | | /* Get container info */ |
301 | 0 | if (H5VL_file_get(file, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) |
302 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get container info"); |
303 | | |
304 | | /* Retrieve min encode size (when references have no vlen part) */ |
305 | 0 | memset(&fixed_ref, 0, sizeof(fixed_ref)); |
306 | 0 | fixed_ref.type = (int8_t)H5R_OBJECT2; |
307 | 0 | fixed_ref.token_size = (uint8_t)cont_info.token_size; |
308 | 0 | if (H5R__encode(NULL, &fixed_ref, NULL, &ref_encode_size, 0) < 0) |
309 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't get encode size"); |
310 | | |
311 | | /* Size on disk, memory size is different */ |
312 | 0 | dt->shared->size = |
313 | 0 | MAX(sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE + cont_info.blob_id_size, ref_encode_size); |
314 | 0 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
315 | | |
316 | | /* Set up the function pointers to access the information on |
317 | | * disk. Region and attribute references are stored identically |
318 | | * on disk, so use the same functions. |
319 | | */ |
320 | 0 | dt->shared->u.atomic.u.r.cls = &H5T_ref_disk_g; |
321 | 0 | } |
322 | 16 | break; |
323 | | |
324 | 16 | case H5T_LOC_BADLOC: |
325 | | /* Allow undefined location. In H5Odtype.c, H5O_dtype_decode sets undefined |
326 | | * location for reference type and leaves it for the caller to decide. |
327 | | */ |
328 | 0 | dt->shared->u.atomic.u.r.loc = H5T_LOC_BADLOC; |
329 | | |
330 | | /* Reset file pointer */ |
331 | 0 | dt->shared->u.atomic.u.r.file = NULL; |
332 | | |
333 | | /* Reset the function pointers */ |
334 | 0 | dt->shared->u.atomic.u.r.cls = NULL; |
335 | |
|
336 | 0 | break; |
337 | | |
338 | 0 | case H5T_LOC_MAXLOC: /* MAXLOC is invalid */ |
339 | 0 | default: |
340 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "invalid reference datatype location"); |
341 | 22 | } /* end switch */ |
342 | | |
343 | | /* Indicate that the location changed */ |
344 | 22 | ret_value = true; |
345 | | |
346 | 38 | done: |
347 | 38 | FUNC_LEAVE_NOAPI(ret_value) |
348 | 38 | } /* end H5T__ref_set_loc() */ |
349 | | |
350 | | /*------------------------------------------------------------------------- |
351 | | * Function: H5T__ref_mem_isnull |
352 | | * |
353 | | * Purpose: Check if it's a NULL / uninitialized reference. |
354 | | * |
355 | | * Return: Non-negative on success/Negative on failure |
356 | | * |
357 | | *------------------------------------------------------------------------- |
358 | | */ |
359 | | static herr_t |
360 | | H5T__ref_mem_isnull(const H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, bool *isnull) |
361 | 0 | { |
362 | 0 | const unsigned char zeros[H5T_REF_MEM_SIZE] = {0}; |
363 | 0 | herr_t ret_value = SUCCEED; |
364 | |
|
365 | 0 | FUNC_ENTER_PACKAGE_NOERR |
366 | 0 | H5T_REF_LOG_DEBUG(""); |
367 | | |
368 | | /* Check parameters */ |
369 | 0 | assert(src_buf); |
370 | 0 | assert(isnull); |
371 | |
|
372 | 0 | *isnull = (0 == memcmp(src_buf, zeros, H5T_REF_MEM_SIZE)) ? true : false; |
373 | |
|
374 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
375 | 0 | } /* end H5T__ref_mem_isnull() */ |
376 | | |
377 | | /*------------------------------------------------------------------------- |
378 | | * Function: H5T__ref_mem_setnull |
379 | | * |
380 | | * Purpose: Set a reference as NULL / uninitialized. |
381 | | * |
382 | | * Return: Non-negative on success/Negative on failure |
383 | | * |
384 | | *------------------------------------------------------------------------- |
385 | | */ |
386 | | static herr_t |
387 | | H5T__ref_mem_setnull(H5VL_object_t H5_ATTR_UNUSED *dst_file, void *dst_buf, H5_ATTR_UNUSED void *bg_buf) |
388 | 0 | { |
389 | 0 | herr_t ret_value = SUCCEED; |
390 | |
|
391 | 0 | FUNC_ENTER_PACKAGE_NOERR |
392 | 0 | H5T_REF_LOG_DEBUG(""); |
393 | |
|
394 | 0 | memset(dst_buf, 0, H5T_REF_MEM_SIZE); |
395 | |
|
396 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
397 | 0 | } /* end H5T__ref_mem_setnull() */ |
398 | | |
399 | | /*------------------------------------------------------------------------- |
400 | | * Function: H5T__ref_mem_getsize |
401 | | * |
402 | | * Purpose: Retrieves the size of a memory based reference. |
403 | | * |
404 | | * Return: Non-negative on success/zero on failure |
405 | | * |
406 | | *------------------------------------------------------------------------- |
407 | | */ |
408 | | static size_t |
409 | | H5T__ref_mem_getsize(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, |
410 | | size_t H5_ATTR_UNUSED src_size, H5VL_object_t *dst_file, bool *dst_copy) |
411 | 0 | { |
412 | 0 | H5VL_object_t *vol_obj = NULL; /* VOL object for src ref's location */ |
413 | 0 | const H5R_ref_priv_t *src_ref = (const H5R_ref_priv_t *)src_buf; |
414 | 0 | char *file_name_buf_dyn = |
415 | 0 | NULL; /* Pointer to dynamically allocated buffer for file name, if static buffer is too small */ |
416 | 0 | unsigned flags = 0; /* References flags */ |
417 | 0 | size_t ret_value = 0; /* Return value */ |
418 | |
|
419 | 0 | FUNC_ENTER_PACKAGE |
420 | 0 | H5T_REF_LOG_DEBUG(""); |
421 | | |
422 | | /* Sanity check */ |
423 | 0 | assert(src_buf); |
424 | 0 | assert(src_size == H5T_REF_MEM_SIZE); |
425 | |
|
426 | 0 | if (NULL != dst_file) { |
427 | 0 | bool files_equal = true; /* Whether src & dst references are in same file */ |
428 | | |
429 | | /* Retrieve VOL object */ |
430 | 0 | if (NULL == (vol_obj = H5VL_vol_object(src_ref->loc_id))) |
431 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid location identifier"); |
432 | | |
433 | | /* Set external flag if referenced file is not destination file */ |
434 | 0 | if (H5VL_file_is_same(vol_obj, dst_file, &files_equal) < 0) |
435 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOMPARE, 0, "can't check if files are equal"); |
436 | 0 | flags |= !files_equal ? H5R_IS_EXTERNAL : 0; |
437 | 0 | } |
438 | | |
439 | | /* Force re-calculating encoding size if any flags are set */ |
440 | 0 | if (flags || !src_ref->encode_size) { |
441 | 0 | H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ |
442 | 0 | char *file_name = NULL; /* Actual file name */ |
443 | 0 | char file_name_buf_static[256]; /* File name */ |
444 | 0 | size_t file_name_len = 0; /* Length of file name */ |
445 | | |
446 | | /* Pass the correct encoding version for the selection depending on the |
447 | | * file libver bounds, this is later retrieved in H5S hyper encode */ |
448 | 0 | if (src_ref->type == (int8_t)H5R_DATASET_REGION2) { |
449 | 0 | bool is_native = false; /* Whether the dest. file is using the native VOL connector */ |
450 | | |
451 | | /* Check if using native VOL connector */ |
452 | 0 | if (H5VL_object_is_native(dst_file, &is_native) < 0) |
453 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't query if file uses native VOL connector"); |
454 | | |
455 | | /* Set the file's libver bounds if using the native VOL connector */ |
456 | 0 | if (is_native) { |
457 | 0 | H5F_t *dst_f; /* Native file struct */ |
458 | |
|
459 | 0 | if (NULL == (dst_f = (H5F_t *)H5VL_object_data(dst_file))) |
460 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid VOL object"); |
461 | 0 | H5CX_set_libver_bounds(dst_f); |
462 | 0 | } /* end if */ |
463 | 0 | else |
464 | 0 | H5CX_set_libver_bounds(NULL); |
465 | 0 | } /* end if */ |
466 | | |
467 | | /* Set up VOL callback arguments */ |
468 | 0 | vol_cb_args.op_type = H5VL_FILE_GET_NAME; |
469 | 0 | vol_cb_args.args.get_name.type = H5I_FILE; |
470 | 0 | vol_cb_args.args.get_name.buf_size = sizeof(file_name_buf_static); |
471 | 0 | vol_cb_args.args.get_name.buf = file_name_buf_static; |
472 | 0 | vol_cb_args.args.get_name.file_name_len = &file_name_len; |
473 | | |
474 | | /* Get file name */ |
475 | 0 | if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) |
476 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name"); |
477 | | |
478 | | /* Check if we need to allocate a buffer for the file name */ |
479 | 0 | if (file_name_len >= sizeof(file_name_buf_static)) { |
480 | | /* Allocate file name buffer */ |
481 | 0 | if (NULL == (file_name_buf_dyn = H5MM_malloc(file_name_len + 1))) |
482 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, 0, "can't allocate space for file name"); |
483 | | |
484 | | /* Update VOL callback arguments */ |
485 | 0 | vol_cb_args.args.get_name.buf_size = file_name_len + 1; |
486 | 0 | vol_cb_args.args.get_name.buf = file_name_buf_dyn; |
487 | | |
488 | | /* Get file name again */ |
489 | 0 | if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) |
490 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name"); |
491 | | |
492 | 0 | file_name = file_name_buf_dyn; |
493 | 0 | } /* end if */ |
494 | 0 | else |
495 | 0 | file_name = file_name_buf_static; |
496 | | |
497 | | /* Determine encoding size */ |
498 | 0 | if (H5R__encode(file_name, src_ref, NULL, &ret_value, flags) < 0) |
499 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, 0, "unable to determine encoding size"); |
500 | 0 | } /* end if */ |
501 | 0 | else { |
502 | | /* Can do a direct copy and skip blob decoding */ |
503 | 0 | if (src_ref->type == (int8_t)H5R_OBJECT2) |
504 | 0 | *dst_copy = true; |
505 | | |
506 | | /* Get cached encoding size */ |
507 | 0 | ret_value = src_ref->encode_size; |
508 | 0 | } /* end else */ |
509 | | |
510 | 0 | done: |
511 | 0 | H5MM_xfree(file_name_buf_dyn); |
512 | |
|
513 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
514 | 0 | } /* end H5T__ref_mem_getsize() */ |
515 | | |
516 | | /*------------------------------------------------------------------------- |
517 | | * Function: H5T__ref_mem_read |
518 | | * |
519 | | * Purpose: "Reads" the memory based reference into a buffer |
520 | | * |
521 | | * Return: Non-negative on success/Negative on failure |
522 | | * |
523 | | *------------------------------------------------------------------------- |
524 | | */ |
525 | | static herr_t |
526 | | H5T__ref_mem_read(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, size_t H5_ATTR_UNUSED src_size, |
527 | | H5VL_object_t *dst_file, void *dst_buf, size_t dst_size) |
528 | 0 | { |
529 | 0 | H5VL_object_t *vol_obj; /* VOL object for src ref's location */ |
530 | 0 | const H5R_ref_priv_t *src_ref = (const H5R_ref_priv_t *)src_buf; |
531 | 0 | bool files_equal = true; /* Whether src & dst references are in same file */ |
532 | 0 | char *file_name = NULL; /* Actual file name */ |
533 | 0 | char file_name_buf_static[256] = {'\0'}; /* File name */ |
534 | 0 | char *file_name_buf_dyn = |
535 | 0 | NULL; /* Pointer to dynamically allocated buffer for file name, if static buffer is too small */ |
536 | 0 | unsigned flags = 0; /* References flags */ |
537 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
538 | |
|
539 | 0 | FUNC_ENTER_PACKAGE |
540 | 0 | H5T_REF_LOG_DEBUG(""); |
541 | | |
542 | | /* Sanity check */ |
543 | 0 | assert(src_buf); |
544 | 0 | assert(src_size == H5T_REF_MEM_SIZE); |
545 | 0 | assert(dst_buf); |
546 | 0 | assert(dst_size); |
547 | | |
548 | | /* Memory-to-memory conversion to support vlen conversion */ |
549 | 0 | if (NULL == dst_file) { |
550 | 0 | H5MM_memcpy(dst_buf, src_buf, dst_size); |
551 | 0 | HGOTO_DONE(ret_value); |
552 | 0 | } |
553 | | |
554 | | /* Retrieve VOL object */ |
555 | 0 | if (NULL == (vol_obj = H5VL_vol_object(src_ref->loc_id))) |
556 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid location identifier"); |
557 | | |
558 | | /* Set external flag if referenced file is not destination file */ |
559 | 0 | if (H5VL_file_is_same(vol_obj, dst_file, &files_equal) < 0) |
560 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOMPARE, FAIL, "can't check if files are equal"); |
561 | 0 | flags |= !files_equal ? H5R_IS_EXTERNAL : 0; |
562 | | |
563 | | /* Pass the correct encoding version for the selection depending on the |
564 | | * file libver bounds, this is later retrieved in H5S hyper encode */ |
565 | 0 | if (src_ref->type == (int8_t)H5R_DATASET_REGION2) { |
566 | 0 | bool is_native = false; /* Whether the dest. file is using the native VOL connector */ |
567 | | |
568 | | /* Check if using native VOL connector */ |
569 | 0 | if (H5VL_object_is_native(dst_file, &is_native) < 0) |
570 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't query if file uses native VOL connector"); |
571 | | |
572 | | /* Set the file's libver bounds if using the native VOL connector */ |
573 | 0 | if (is_native) { |
574 | 0 | H5F_t *dst_f; |
575 | |
|
576 | 0 | if (NULL == (dst_f = (H5F_t *)H5VL_object_data(dst_file))) |
577 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid VOL object"); |
578 | 0 | H5CX_set_libver_bounds(dst_f); |
579 | 0 | } /* end if */ |
580 | 0 | else |
581 | 0 | H5CX_set_libver_bounds(NULL); |
582 | 0 | } /* end if */ |
583 | | |
584 | | /* Get file name (if external reference) */ |
585 | 0 | if (flags) { |
586 | 0 | H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */ |
587 | 0 | size_t file_name_len = 0; /* Length of file name */ |
588 | | |
589 | | /* Set up VOL callback arguments */ |
590 | 0 | vol_cb_args.op_type = H5VL_FILE_GET_NAME; |
591 | 0 | vol_cb_args.args.get_name.type = H5I_FILE; |
592 | 0 | vol_cb_args.args.get_name.buf_size = sizeof(file_name_buf_static); |
593 | 0 | vol_cb_args.args.get_name.buf = file_name_buf_static; |
594 | 0 | vol_cb_args.args.get_name.file_name_len = &file_name_len; |
595 | | |
596 | | /* Get file name */ |
597 | 0 | if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) |
598 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name"); |
599 | | |
600 | | /* Check if we need to allocate a buffer for the file name */ |
601 | 0 | if (file_name_len >= sizeof(file_name_buf_static)) { |
602 | | /* Allocate file name buffer */ |
603 | 0 | if (NULL == (file_name_buf_dyn = H5MM_malloc(file_name_len + 1))) |
604 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTALLOC, 0, "can't allocate space for file name"); |
605 | | |
606 | | /* Update VOL callback arguments */ |
607 | 0 | vol_cb_args.args.get_name.buf_size = file_name_len + 1; |
608 | 0 | vol_cb_args.args.get_name.buf = file_name_buf_dyn; |
609 | | |
610 | | /* Get file name again */ |
611 | 0 | if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, NULL) < 0) |
612 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't get file name"); |
613 | | |
614 | 0 | file_name = file_name_buf_dyn; |
615 | 0 | } /* end if */ |
616 | 0 | else |
617 | 0 | file_name = file_name_buf_static; |
618 | 0 | } /* end if */ |
619 | | |
620 | | /* Encode reference */ |
621 | 0 | if (H5R__encode(file_name, src_ref, (unsigned char *)dst_buf, &dst_size, flags) < 0) |
622 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTENCODE, FAIL, "Cannot encode reference"); |
623 | | |
624 | 0 | done: |
625 | 0 | H5MM_xfree(file_name_buf_dyn); |
626 | |
|
627 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
628 | 0 | } /* end H5T__ref_mem_read() */ |
629 | | |
630 | | /*------------------------------------------------------------------------- |
631 | | * Function: H5T__ref_mem_write |
632 | | * |
633 | | * Purpose: "Writes" the memory reference from a buffer |
634 | | * |
635 | | * Return: Non-negative on success/Negative on failure |
636 | | * |
637 | | *------------------------------------------------------------------------- |
638 | | */ |
639 | | static herr_t |
640 | | H5T__ref_mem_write(H5VL_object_t *src_file, const void *src_buf, size_t src_size, H5R_type_t src_type, |
641 | | H5VL_object_t H5_ATTR_UNUSED *dst_file, void *dst_buf, |
642 | | size_t H5_ATTR_NDEBUG_UNUSED dst_size, void H5_ATTR_UNUSED *bg_buf) |
643 | 0 | { |
644 | 0 | H5F_t *src_f = NULL; |
645 | 0 | hid_t file_id = H5I_INVALID_HID; |
646 | 0 | H5R_ref_priv_t tmp_ref; /* Temporary reference to decode into */ |
647 | 0 | herr_t ret_value = SUCCEED; |
648 | |
|
649 | 0 | FUNC_ENTER_PACKAGE |
650 | 0 | H5T_REF_LOG_DEBUG(""); |
651 | | |
652 | | /* Sanity check */ |
653 | 0 | assert(src_buf); |
654 | 0 | assert(src_size); |
655 | 0 | assert(dst_buf); |
656 | 0 | assert(dst_size == H5T_REF_MEM_SIZE); |
657 | | |
658 | | /* Memory-to-memory conversion to support vlen conversion */ |
659 | 0 | if (NULL == src_file) { |
660 | 0 | H5MM_memcpy(dst_buf, src_buf, src_size); |
661 | 0 | HGOTO_DONE(ret_value); |
662 | 0 | } |
663 | | |
664 | | #ifndef NDEBUG |
665 | | if ((src_type == H5R_OBJECT1) || (src_type == H5R_DATASET_REGION1)) { |
666 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
667 | | |
668 | | /* Check if using native VOL connector */ |
669 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
670 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector"); |
671 | | |
672 | | /* Must use native VOL connector for this operation */ |
673 | | assert(is_native); |
674 | | } |
675 | | #endif /* NDEBUG */ |
676 | | |
677 | | /* Retrieve file from VOL object */ |
678 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
679 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
680 | | |
681 | | /* Make sure reference buffer is correctly initialized */ |
682 | 0 | memset(&tmp_ref, 0, sizeof(tmp_ref)); |
683 | |
|
684 | 0 | switch (src_type) { |
685 | 0 | case H5R_OBJECT1: { |
686 | 0 | size_t token_size = H5F_SIZEOF_ADDR(src_f); |
687 | |
|
688 | 0 | if (H5R__create_object((const H5O_token_t *)src_buf, token_size, &tmp_ref) < 0) |
689 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create object reference"); |
690 | 0 | } break; |
691 | | |
692 | 0 | case H5R_DATASET_REGION1: { |
693 | 0 | const struct H5Tref_dsetreg *src_reg = (const struct H5Tref_dsetreg *)src_buf; |
694 | 0 | size_t token_size = H5F_SIZEOF_ADDR(src_f); |
695 | |
|
696 | 0 | if (H5R__create_region(&src_reg->token, token_size, src_reg->space, &tmp_ref) < 0) |
697 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create region reference"); |
698 | | |
699 | | /* create_region creates its internal copy of the space */ |
700 | 0 | if (H5S_close(src_reg->space) < 0) |
701 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "Cannot close dataspace"); |
702 | 0 | } break; |
703 | | |
704 | 0 | case H5R_DATASET_REGION2: |
705 | | /* Pass the correct encoding version for the selection depending on the |
706 | | * file libver bounds, this is later retrieved in H5S hyper decode */ |
707 | 0 | H5CX_set_libver_bounds(src_f); |
708 | | /* FALLTHROUGH */ |
709 | 0 | H5_ATTR_FALLTHROUGH |
710 | 0 | case H5R_OBJECT2: |
711 | 0 | case H5R_ATTR: |
712 | | /* Decode reference */ |
713 | 0 | if (H5R__decode((const unsigned char *)src_buf, &src_size, &tmp_ref) < 0) |
714 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Cannot decode reference"); |
715 | 0 | break; |
716 | | |
717 | 0 | case H5R_BADTYPE: |
718 | 0 | case H5R_MAXTYPE: |
719 | 0 | default: |
720 | 0 | assert("unknown reference type" && 0); |
721 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)"); |
722 | 0 | } /* end switch */ |
723 | | |
724 | | /* If no filename set, this is not an external reference */ |
725 | 0 | if (NULL == H5R_REF_FILENAME(&tmp_ref)) { |
726 | | /* TODO temporary hack to retrieve file object */ |
727 | 0 | if ((file_id = H5F_get_file_id(src_file, H5I_FILE, false)) < 0) |
728 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); |
729 | | |
730 | | /* Attach loc ID to reference and hold reference to it, this is a |
731 | | * user exposed reference so set app_ref to true. */ |
732 | 0 | if (H5R__set_loc_id(&tmp_ref, file_id, true, true) < 0) |
733 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to attach location id to reference"); |
734 | 0 | } /* end if */ |
735 | | |
736 | | /* Set output info */ |
737 | 0 | H5MM_memcpy(dst_buf, &tmp_ref, sizeof(tmp_ref)); |
738 | |
|
739 | 0 | done: |
740 | 0 | if ((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) |
741 | 0 | HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on location id"); |
742 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
743 | 0 | } /* end H5T__ref_mem_write() */ |
744 | | |
745 | | /*------------------------------------------------------------------------- |
746 | | * Function: H5T__ref_disk_isnull |
747 | | * |
748 | | * Purpose: Check if it's a NULL / uninitialized reference. |
749 | | * |
750 | | * Return: Non-negative on success/Negative on failure |
751 | | * |
752 | | *------------------------------------------------------------------------- |
753 | | */ |
754 | | /* |
755 | | * It is the correct thing to do to have the reference buffer |
756 | | * be const-qualified here, but the VOL "blob specific" routine |
757 | | * needs a non-const pointer since an operation might modify |
758 | | * the "blob". Disable this warning here (at least temporarily) |
759 | | * for this reason. |
760 | | */ |
761 | | H5_WARN_CAST_AWAY_CONST_OFF |
762 | | static herr_t |
763 | | H5T__ref_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, bool *isnull) |
764 | 0 | { |
765 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
766 | 0 | H5R_type_t ref_type; |
767 | 0 | herr_t ret_value = SUCCEED; |
768 | |
|
769 | 0 | FUNC_ENTER_PACKAGE |
770 | 0 | H5T_REF_LOG_DEBUG(""); |
771 | | |
772 | | /* Check parameters */ |
773 | 0 | assert(src_file); |
774 | 0 | assert(src_buf); |
775 | 0 | assert(isnull); |
776 | | |
777 | | /* Try to check encoded reference type */ |
778 | 0 | ref_type = (H5R_type_t)*p++; |
779 | 0 | if (ref_type) { |
780 | | /* This is a valid reference */ |
781 | 0 | *isnull = false; |
782 | 0 | } |
783 | 0 | else { |
784 | 0 | H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ |
785 | | |
786 | | /* Skip the size / header */ |
787 | 0 | p = (const uint8_t *)src_buf + H5R_ENCODE_HEADER_SIZE + sizeof(uint32_t); |
788 | | |
789 | | /* Set up VOL callback arguments */ |
790 | 0 | vol_cb_args.op_type = H5VL_BLOB_ISNULL; |
791 | 0 | vol_cb_args.args.is_null.isnull = isnull; |
792 | | |
793 | | /* Check if blob ID is "nil" */ |
794 | 0 | if (H5VL_blob_specific(src_file, (void *)p, &vol_cb_args) < 0) |
795 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'"); |
796 | 0 | } |
797 | | |
798 | 0 | done: |
799 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
800 | 0 | } /* end H5T__ref_disk_isnull() */ |
801 | | H5_WARN_CAST_AWAY_CONST_ON |
802 | | |
803 | | /*------------------------------------------------------------------------- |
804 | | * Function: H5T__ref_disk_setnull |
805 | | * |
806 | | * Purpose: Set a reference as NULL / uninitialized. |
807 | | * |
808 | | * Return: Non-negative on success/Negative on failure |
809 | | * |
810 | | *------------------------------------------------------------------------- |
811 | | */ |
812 | | static herr_t |
813 | | H5T__ref_disk_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf) |
814 | 0 | { |
815 | 0 | H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ |
816 | 0 | uint8_t *q = (uint8_t *)dst_buf; |
817 | 0 | uint8_t *p_bg = (uint8_t *)bg_buf; |
818 | 0 | herr_t ret_value = SUCCEED; |
819 | |
|
820 | 0 | FUNC_ENTER_PACKAGE |
821 | 0 | H5T_REF_LOG_DEBUG(""); |
822 | |
|
823 | 0 | assert(dst_file); |
824 | 0 | assert(dst_buf); |
825 | | |
826 | | /* TODO Should get rid of bg stuff */ |
827 | 0 | if (p_bg) { |
828 | | /* Skip the size / header */ |
829 | 0 | p_bg += (sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE); |
830 | | |
831 | | /* Set up VOL callback arguments */ |
832 | 0 | vol_cb_args.op_type = H5VL_BLOB_DELETE; |
833 | | |
834 | | /* Remove blob for old data */ |
835 | 0 | if (H5VL_blob_specific(dst_file, (void *)p_bg, &vol_cb_args) < 0) |
836 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob"); |
837 | 0 | } /* end if */ |
838 | | |
839 | | /* Copy header manually so that it does not get encoded into the blob */ |
840 | 0 | memset(q, 0, H5R_ENCODE_HEADER_SIZE); |
841 | 0 | q += H5R_ENCODE_HEADER_SIZE; |
842 | | |
843 | | /* Set the size */ |
844 | 0 | UINT32ENCODE(q, 0); |
845 | | |
846 | | /* Set up VOL callback arguments */ |
847 | 0 | vol_cb_args.op_type = H5VL_BLOB_SETNULL; |
848 | | |
849 | | /* Set blob ID to "nil" */ |
850 | 0 | if (H5VL_blob_specific(dst_file, q, &vol_cb_args) < 0) |
851 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'"); |
852 | | |
853 | 0 | done: |
854 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
855 | 0 | } /* end H5T__ref_disk_setnull() */ |
856 | | |
857 | | /*------------------------------------------------------------------------- |
858 | | * Function: H5T__ref_disk_getsize |
859 | | * |
860 | | * Purpose: Retrieves the length of a disk based reference. |
861 | | * |
862 | | * Return: Non-negative value (cannot fail) |
863 | | * |
864 | | *------------------------------------------------------------------------- |
865 | | */ |
866 | | static size_t |
867 | | H5T__ref_disk_getsize(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, size_t src_size, |
868 | | H5VL_object_t H5_ATTR_UNUSED *dst_file, bool *dst_copy) |
869 | 0 | { |
870 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
871 | 0 | unsigned flags; |
872 | 0 | H5R_type_t ref_type; |
873 | 0 | size_t ret_value = 0; |
874 | |
|
875 | 0 | FUNC_ENTER_PACKAGE |
876 | 0 | H5T_REF_LOG_DEBUG(""); |
877 | |
|
878 | 0 | assert(src_buf); |
879 | | |
880 | | /* Set reference type */ |
881 | 0 | ref_type = (H5R_type_t)*p++; |
882 | 0 | if (ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) |
883 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid reference type"); |
884 | | |
885 | | /* Set flags */ |
886 | 0 | flags = (unsigned)*p++; |
887 | |
|
888 | 0 | if (!(flags & H5R_IS_EXTERNAL) && (ref_type == H5R_OBJECT2)) { |
889 | | /* Can do a direct copy and skip blob decoding */ |
890 | 0 | *dst_copy = true; |
891 | |
|
892 | 0 | ret_value = src_size; |
893 | 0 | } /* end if */ |
894 | 0 | else { |
895 | | /* Retrieve encoded data size */ |
896 | 0 | UINT32DECODE(p, ret_value); |
897 | | |
898 | | /* Add size of the header */ |
899 | 0 | ret_value += H5R_ENCODE_HEADER_SIZE; |
900 | 0 | } /* end else */ |
901 | |
|
902 | 0 | done: |
903 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
904 | 0 | } /* end H5T__ref_disk_getsize() */ |
905 | | |
906 | | /*------------------------------------------------------------------------- |
907 | | * Function: H5T__ref_disk_read |
908 | | * |
909 | | * Purpose: Reads the disk based reference into a buffer |
910 | | * |
911 | | * Return: Non-negative on success/Negative on failure |
912 | | * |
913 | | *------------------------------------------------------------------------- |
914 | | */ |
915 | | static herr_t |
916 | | H5T__ref_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t H5_ATTR_NDEBUG_UNUSED src_size, |
917 | | H5VL_object_t H5_ATTR_UNUSED *dst_file, void *dst_buf, size_t dst_size) |
918 | 0 | { |
919 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
920 | 0 | uint8_t *q = (uint8_t *)dst_buf; |
921 | 0 | size_t blob_size = dst_size; |
922 | 0 | herr_t ret_value = SUCCEED; |
923 | |
|
924 | 0 | FUNC_ENTER_PACKAGE |
925 | 0 | H5T_REF_LOG_DEBUG(""); |
926 | |
|
927 | 0 | assert(src_file); |
928 | 0 | assert(src_buf); |
929 | 0 | assert(dst_buf); |
930 | 0 | assert(dst_size); |
931 | | |
932 | | /* Copy header manually */ |
933 | 0 | H5MM_memcpy(q, p, H5R_ENCODE_HEADER_SIZE); |
934 | 0 | p += H5R_ENCODE_HEADER_SIZE; |
935 | 0 | q += H5R_ENCODE_HEADER_SIZE; |
936 | 0 | blob_size -= H5R_ENCODE_HEADER_SIZE; |
937 | | |
938 | | /* Skip the size */ |
939 | 0 | p += sizeof(uint32_t); |
940 | 0 | assert(src_size > (H5R_ENCODE_HEADER_SIZE + sizeof(uint32_t))); |
941 | | |
942 | | /* Retrieve blob */ |
943 | 0 | if (H5VL_blob_get(src_file, p, q, blob_size, NULL) < 0) |
944 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get blob"); |
945 | | |
946 | 0 | done: |
947 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
948 | 0 | } /* end H5T__ref_disk_read() */ |
949 | | |
950 | | /*------------------------------------------------------------------------- |
951 | | * Function: H5T__ref_disk_write |
952 | | * |
953 | | * Purpose: Writes the disk based reference from a buffer |
954 | | * |
955 | | * Return: Non-negative on success/Negative on failure |
956 | | * |
957 | | *------------------------------------------------------------------------- |
958 | | */ |
959 | | static herr_t |
960 | | H5T__ref_disk_write(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, size_t src_size, |
961 | | H5R_type_t H5_ATTR_UNUSED src_type, H5VL_object_t *dst_file, void *dst_buf, |
962 | | size_t H5_ATTR_NDEBUG_UNUSED dst_size, void *bg_buf) |
963 | 0 | { |
964 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
965 | 0 | uint8_t *q = (uint8_t *)dst_buf; |
966 | 0 | uint8_t *p_bg = (uint8_t *)bg_buf; |
967 | 0 | herr_t ret_value = SUCCEED; |
968 | |
|
969 | 0 | FUNC_ENTER_PACKAGE |
970 | 0 | H5T_REF_LOG_DEBUG(""); |
971 | |
|
972 | 0 | assert(src_buf); |
973 | 0 | assert(src_size); |
974 | 0 | assert(dst_file); |
975 | 0 | assert(dst_buf); |
976 | | |
977 | | /* TODO Should get rid of bg stuff */ |
978 | 0 | if (p_bg) { |
979 | 0 | H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ |
980 | | |
981 | | /* Skip the size / header */ |
982 | 0 | p_bg += (sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE); |
983 | |
|
984 | | #ifndef NDEBUG |
985 | | size_t p_buf_size_left = dst_size; |
986 | | assert(p_buf_size_left > (sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE)); |
987 | | #endif |
988 | | |
989 | | /* Set up VOL callback arguments */ |
990 | 0 | vol_cb_args.op_type = H5VL_BLOB_DELETE; |
991 | | |
992 | | /* Remove blob for old data */ |
993 | 0 | if (H5VL_blob_specific(dst_file, (void *)p_bg, &vol_cb_args) < 0) |
994 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob"); |
995 | 0 | } /* end if */ |
996 | | |
997 | | /* Copy header manually so that it does not get encoded into the blob */ |
998 | 0 | H5MM_memcpy(q, p, H5R_ENCODE_HEADER_SIZE); |
999 | 0 | p += H5R_ENCODE_HEADER_SIZE; |
1000 | 0 | q += H5R_ENCODE_HEADER_SIZE; |
1001 | 0 | src_size -= H5R_ENCODE_HEADER_SIZE; |
1002 | |
|
1003 | | #ifndef NDEBUG |
1004 | | { |
1005 | | size_t buf_size_left = dst_size - sizeof(uint32_t); |
1006 | | assert(buf_size_left > sizeof(uint32_t)); |
1007 | | } |
1008 | | #endif |
1009 | | |
1010 | | /* Set the size */ |
1011 | 0 | UINT32ENCODE(q, src_size); |
1012 | | |
1013 | | /* Store blob */ |
1014 | 0 | if (H5VL_blob_put(dst_file, p, src_size, q, NULL) < 0) |
1015 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to put blob"); |
1016 | | |
1017 | 0 | done: |
1018 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1019 | 0 | } /* end H5T__ref_disk_write() */ |
1020 | | |
1021 | | /*------------------------------------------------------------------------- |
1022 | | * Function: H5T__ref_obj_disk_isnull |
1023 | | * |
1024 | | * Purpose: Check if it's a NULL / uninitialized reference. |
1025 | | * |
1026 | | * Return: Non-negative on success/Negative on failure |
1027 | | * |
1028 | | *------------------------------------------------------------------------- |
1029 | | */ |
1030 | | static herr_t |
1031 | | H5T__ref_obj_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, bool *isnull) |
1032 | 0 | { |
1033 | 0 | H5F_t *src_f; |
1034 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
1035 | 0 | haddr_t addr; |
1036 | 0 | herr_t ret_value = SUCCEED; |
1037 | |
|
1038 | 0 | FUNC_ENTER_PACKAGE |
1039 | 0 | H5T_REF_LOG_DEBUG(""); |
1040 | | |
1041 | | /* Check parameters */ |
1042 | 0 | assert(src_file); |
1043 | 0 | assert(src_buf); |
1044 | 0 | assert(isnull); |
1045 | |
|
1046 | | #ifndef NDEBUG |
1047 | | { |
1048 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1049 | | |
1050 | | /* Check if using native VOL connector */ |
1051 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1052 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector"); |
1053 | | |
1054 | | /* Must use native VOL connector for this operation */ |
1055 | | assert(is_native); |
1056 | | } |
1057 | | #endif /* NDEBUG */ |
1058 | | |
1059 | | /* Retrieve file from VOL object */ |
1060 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1061 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
1062 | | |
1063 | | /* Get the object address */ |
1064 | 0 | H5F_addr_decode(src_f, &p, &addr); |
1065 | | |
1066 | | /* Check if heap address is 'nil' */ |
1067 | 0 | *isnull = (addr == 0) ? true : false; |
1068 | |
|
1069 | 0 | done: |
1070 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1071 | 0 | } /* end H5T__ref_obj_disk_isnull() */ |
1072 | | |
1073 | | /*------------------------------------------------------------------------- |
1074 | | * Function: H5T__ref_obj_disk_getsize |
1075 | | * |
1076 | | * Purpose: Retrieves the length of a disk based reference. |
1077 | | * |
1078 | | * Return: Non-negative value (cannot fail) |
1079 | | * |
1080 | | *------------------------------------------------------------------------- |
1081 | | */ |
1082 | | static size_t |
1083 | | H5T__ref_obj_disk_getsize(H5VL_object_t *src_file, const void H5_ATTR_UNUSED *src_buf, |
1084 | | size_t H5_ATTR_UNUSED src_size, H5VL_object_t H5_ATTR_UNUSED *dst_file, |
1085 | | bool H5_ATTR_UNUSED *dst_copy) |
1086 | 0 | { |
1087 | 0 | H5F_t *src_f; |
1088 | 0 | size_t ret_value = 0; |
1089 | |
|
1090 | 0 | FUNC_ENTER_PACKAGE |
1091 | 0 | H5T_REF_LOG_DEBUG(""); |
1092 | |
|
1093 | 0 | assert(src_file); |
1094 | 0 | assert(src_buf); |
1095 | |
|
1096 | | #ifndef NDEBUG |
1097 | | { |
1098 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1099 | | |
1100 | | /* Check if using native VOL connector */ |
1101 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1102 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't query if file uses native VOL connector"); |
1103 | | |
1104 | | /* Must use native VOL connector for this operation */ |
1105 | | assert(is_native); |
1106 | | } |
1107 | | #endif /* NDEBUG */ |
1108 | | |
1109 | | /* Retrieve file from VOL object */ |
1110 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1111 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid VOL object"); |
1112 | | |
1113 | 0 | assert(src_size == H5T_REF_OBJ_DISK_SIZE(src_f)); |
1114 | |
|
1115 | 0 | ret_value = H5T_REF_OBJ_DISK_SIZE(src_f); |
1116 | |
|
1117 | 0 | done: |
1118 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1119 | 0 | } /* end H5T__ref_obj_disk_getsize() */ |
1120 | | |
1121 | | /*------------------------------------------------------------------------- |
1122 | | * Function: H5T__ref_obj_disk_read |
1123 | | * |
1124 | | * Purpose: Reads the disk based reference into a buffer |
1125 | | * |
1126 | | * Return: Non-negative on success/Negative on failure |
1127 | | * |
1128 | | *------------------------------------------------------------------------- |
1129 | | */ |
1130 | | static herr_t |
1131 | | H5T__ref_obj_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
1132 | | H5VL_object_t H5_ATTR_UNUSED *dst_file, void *dst_buf, size_t H5_ATTR_UNUSED dst_size) |
1133 | 0 | { |
1134 | 0 | H5F_t *src_f; |
1135 | 0 | herr_t ret_value = SUCCEED; |
1136 | |
|
1137 | 0 | FUNC_ENTER_PACKAGE |
1138 | 0 | H5T_REF_LOG_DEBUG(""); |
1139 | |
|
1140 | 0 | assert(src_file); |
1141 | 0 | assert(src_buf); |
1142 | 0 | assert(dst_buf); |
1143 | |
|
1144 | | #ifndef NDEBUG |
1145 | | { |
1146 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1147 | | |
1148 | | /* Check if using native VOL connector */ |
1149 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1150 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector"); |
1151 | | |
1152 | | /* Must use native VOL connector for this operation */ |
1153 | | assert(is_native); |
1154 | | } |
1155 | | #endif /* NDEBUG */ |
1156 | | |
1157 | | /* Retrieve file from VOL object */ |
1158 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1159 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
1160 | | |
1161 | 0 | assert(src_size == H5T_REF_OBJ_DISK_SIZE(src_f)); |
1162 | 0 | assert(dst_size == H5F_SIZEOF_ADDR(src_f)); |
1163 | | |
1164 | | /* Get object address */ |
1165 | 0 | if (H5R__decode_token_obj_compat((const unsigned char *)src_buf, &src_size, (H5O_token_t *)dst_buf, |
1166 | 0 | H5F_SIZEOF_ADDR(src_f)) < 0) |
1167 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address"); |
1168 | | |
1169 | 0 | done: |
1170 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1171 | 0 | } /* end H5T__ref_obj_disk_read() */ |
1172 | | |
1173 | | /*------------------------------------------------------------------------- |
1174 | | * Function: H5T__ref_dsetreg_disk_isnull |
1175 | | * |
1176 | | * Purpose: Check if it's a NULL / uninitialized reference. |
1177 | | * |
1178 | | * Return: Non-negative on success/Negative on failure |
1179 | | * |
1180 | | *------------------------------------------------------------------------- |
1181 | | */ |
1182 | | static herr_t |
1183 | | H5T__ref_dsetreg_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, bool *isnull) |
1184 | 0 | { |
1185 | 0 | H5F_t *src_f; |
1186 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
1187 | 0 | haddr_t addr; |
1188 | 0 | herr_t ret_value = SUCCEED; |
1189 | |
|
1190 | 0 | FUNC_ENTER_PACKAGE |
1191 | 0 | H5T_REF_LOG_DEBUG(""); |
1192 | | |
1193 | | /* Check parameters */ |
1194 | 0 | assert(src_file); |
1195 | 0 | assert(src_buf); |
1196 | 0 | assert(isnull); |
1197 | |
|
1198 | | #ifndef NDEBUG |
1199 | | { |
1200 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1201 | | |
1202 | | /* Check if using native VOL connector */ |
1203 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1204 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector"); |
1205 | | |
1206 | | /* Must use native VOL connector for this operation */ |
1207 | | assert(is_native); |
1208 | | } |
1209 | | #endif /* NDEBUG */ |
1210 | | |
1211 | | /* Retrieve file from VOL object */ |
1212 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1213 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
1214 | | |
1215 | | /* Get the heap address */ |
1216 | 0 | H5F_addr_decode(src_f, &p, &addr); |
1217 | | |
1218 | | /* Check if heap address is 'nil' */ |
1219 | 0 | *isnull = (addr == 0) ? true : false; |
1220 | |
|
1221 | 0 | done: |
1222 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1223 | 0 | } /* end H5T__ref_dsetreg_disk_isnull() */ |
1224 | | |
1225 | | /*------------------------------------------------------------------------- |
1226 | | * Function: H5T__ref_dsetreg_disk_getsize |
1227 | | * |
1228 | | * Purpose: Retrieves the length of a disk based reference. |
1229 | | * |
1230 | | * Return: Non-negative value (cannot fail) |
1231 | | * |
1232 | | *------------------------------------------------------------------------- |
1233 | | */ |
1234 | | static size_t |
1235 | | H5T__ref_dsetreg_disk_getsize(H5VL_object_t H5_ATTR_UNUSED *src_file, const void H5_ATTR_UNUSED *src_buf, |
1236 | | size_t H5_ATTR_UNUSED src_size, H5VL_object_t H5_ATTR_UNUSED *dst_file, |
1237 | | bool H5_ATTR_UNUSED *dst_copy) |
1238 | 0 | { |
1239 | 0 | size_t ret_value = sizeof(struct H5Tref_dsetreg); |
1240 | |
|
1241 | | #ifndef NDEBUG |
1242 | | FUNC_ENTER_PACKAGE |
1243 | | #else |
1244 | 0 | FUNC_ENTER_PACKAGE_NOERR |
1245 | 0 | #endif |
1246 | 0 | H5T_REF_LOG_DEBUG(""); |
1247 | |
|
1248 | 0 | assert(src_buf); |
1249 | |
|
1250 | | #ifndef NDEBUG |
1251 | | { |
1252 | | H5F_t *src_f; |
1253 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1254 | | |
1255 | | /* Check if using native VOL connector */ |
1256 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1257 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't query if file uses native VOL connector"); |
1258 | | |
1259 | | /* Must use native VOL connector for this operation */ |
1260 | | assert(is_native); |
1261 | | |
1262 | | /* Retrieve file from VOL object */ |
1263 | | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1264 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid VOL object"); |
1265 | | |
1266 | | assert(src_size == H5T_REF_DSETREG_DISK_SIZE(src_f)); |
1267 | | } |
1268 | | #endif /* NDEBUG */ |
1269 | |
|
1270 | | #ifndef NDEBUG |
1271 | | done: |
1272 | | #endif |
1273 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1274 | 0 | } /* end H5T__ref_dsetreg_disk_getsize() */ |
1275 | | |
1276 | | /*------------------------------------------------------------------------- |
1277 | | * Function: H5T__ref_dsetreg_disk_read |
1278 | | * |
1279 | | * Purpose: Reads the disk based reference into a buffer |
1280 | | * |
1281 | | * Return: Non-negative on success/Negative on failure |
1282 | | * |
1283 | | *------------------------------------------------------------------------- |
1284 | | */ |
1285 | | static herr_t |
1286 | | H5T__ref_dsetreg_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
1287 | | H5VL_object_t H5_ATTR_UNUSED *dst_file, void *dst_buf, |
1288 | | size_t H5_ATTR_UNUSED dst_size) |
1289 | 0 | { |
1290 | 0 | H5F_t *src_f; |
1291 | 0 | struct H5Tref_dsetreg *dst_reg = (struct H5Tref_dsetreg *)dst_buf; |
1292 | 0 | herr_t ret_value = SUCCEED; |
1293 | |
|
1294 | 0 | FUNC_ENTER_PACKAGE |
1295 | 0 | H5T_REF_LOG_DEBUG(""); |
1296 | |
|
1297 | 0 | assert(src_file); |
1298 | 0 | assert(src_buf); |
1299 | 0 | assert(dst_buf); |
1300 | 0 | assert(dst_size == sizeof(struct H5Tref_dsetreg)); |
1301 | |
|
1302 | | #ifndef NDEBUG |
1303 | | { |
1304 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1305 | | |
1306 | | /* Check if using native VOL connector */ |
1307 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1308 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector"); |
1309 | | |
1310 | | /* Must use native VOL connector for this operation */ |
1311 | | assert(is_native); |
1312 | | } |
1313 | | #endif /* NDEBUG */ |
1314 | | |
1315 | | /* Retrieve file from VOL object */ |
1316 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1317 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
1318 | | |
1319 | 0 | assert(src_size == H5T_REF_DSETREG_DISK_SIZE(src_f)); |
1320 | | |
1321 | | /* Retrieve object address and space */ |
1322 | 0 | if (H5R__decode_token_region_compat(src_f, (const unsigned char *)src_buf, &src_size, &dst_reg->token, |
1323 | 0 | H5F_SIZEOF_ADDR(src_f), &dst_reg->space) < 0) |
1324 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address"); |
1325 | | |
1326 | 0 | done: |
1327 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1328 | 0 | } /* end H5T__ref_dsetreg_disk_read() */ |
1329 | | |
1330 | | /*------------------------------------------------------------------------- |
1331 | | * Function: H5T__ref_reclaim |
1332 | | * |
1333 | | * Purpose: Internal routine to free reference datatypes |
1334 | | * |
1335 | | * Return: Non-negative on success / Negative on failure |
1336 | | * |
1337 | | *------------------------------------------------------------------------- |
1338 | | */ |
1339 | | herr_t |
1340 | | H5T__ref_reclaim(void *elem, const H5T_t *dt) |
1341 | 0 | { |
1342 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
1343 | |
|
1344 | 0 | FUNC_ENTER_PACKAGE |
1345 | 0 | H5T_REF_LOG_DEBUG(""); |
1346 | | |
1347 | | /* Sanity checks */ |
1348 | 0 | assert(elem); |
1349 | 0 | assert(dt && (dt->shared->type == H5T_REFERENCE)); |
1350 | |
|
1351 | 0 | if (dt->shared->u.atomic.u.r.opaque && H5R__destroy((H5R_ref_priv_t *)elem) < 0) |
1352 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "cannot free reference"); |
1353 | | |
1354 | 0 | done: |
1355 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1356 | 0 | } /* end H5T__ref_reclaim() */ |