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 | 1 | #define H5T_REF_MEM_SIZE (H5R_REF_BUF_SIZE) |
38 | 1 | #define H5T_REF_OBJ_MEM_SIZE (H5R_OBJ_REF_BUF_SIZE) |
39 | 1 | #define H5T_REF_DSETREG_MEM_SIZE (H5R_DSET_REG_REF_BUF_SIZE) |
40 | | |
41 | 0 | #define H5T_REF_OBJ_DISK_SIZE(f) (H5F_SIZEOF_ADDR(f)) |
42 | 0 | #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 | 3 | do { \ |
57 | 3 | } 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 | 3 | { |
161 | 3 | htri_t ret_value = false; /* Indicate success, but no location change */ |
162 | | |
163 | 3 | FUNC_ENTER_PACKAGE |
164 | 3 | H5T_REF_LOG_DEBUG("loc=%d", (int)loc); |
165 | | |
166 | 3 | assert(dt); |
167 | | /* f is NULL when loc == H5T_LOC_MEMORY */ |
168 | 3 | assert(loc >= H5T_LOC_BADLOC && loc < H5T_LOC_MAXLOC); |
169 | | |
170 | | /* Only change the location if it's different */ |
171 | 3 | if (loc == dt->shared->u.atomic.u.r.loc && file == dt->shared->u.atomic.u.r.file) |
172 | 0 | HGOTO_DONE(false); |
173 | | |
174 | 3 | switch (loc) { |
175 | 3 | 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 | 3 | dt->shared->u.atomic.u.r.loc = H5T_LOC_MEMORY; |
182 | | |
183 | | /* Release owned file */ |
184 | 3 | 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 | 3 | dt->shared->u.atomic.u.r.file = file; /* file is NULL */ |
192 | | |
193 | 3 | if (dt->shared->u.atomic.u.r.opaque) { |
194 | | /* Size in memory, disk size is different */ |
195 | 1 | dt->shared->size = H5T_REF_MEM_SIZE; |
196 | 1 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
197 | | |
198 | | /* Set up the function pointers to access the reference in memory */ |
199 | 1 | dt->shared->u.atomic.u.r.cls = &H5T_ref_mem_g; |
200 | 1 | } /* end if */ |
201 | 2 | else if (dt->shared->u.atomic.u.r.rtype == H5R_OBJECT1) { |
202 | | /* Size in memory, disk size is different */ |
203 | 1 | dt->shared->size = H5T_REF_OBJ_MEM_SIZE; |
204 | 1 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
205 | | |
206 | | /* Unused for now */ |
207 | 1 | dt->shared->u.atomic.u.r.cls = NULL; |
208 | 1 | } /* end else-if */ |
209 | 1 | else if (dt->shared->u.atomic.u.r.rtype == H5R_DATASET_REGION1) { |
210 | | /* Size in memory, disk size is different */ |
211 | 1 | dt->shared->size = H5T_REF_DSETREG_MEM_SIZE; |
212 | 1 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
213 | | |
214 | | /* Unused for now */ |
215 | 1 | dt->shared->u.atomic.u.r.cls = NULL; |
216 | 1 | } /* end else-if */ |
217 | 0 | else |
218 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid location"); |
219 | 3 | break; |
220 | | |
221 | 3 | case H5T_LOC_DISK: /* Disk based reference datatype */ |
222 | 0 | assert(file); |
223 | | |
224 | | /* Mark this type as being stored on disk */ |
225 | 0 | dt->shared->u.atomic.u.r.loc = H5T_LOC_DISK; |
226 | | |
227 | | /* Set file pointer (since this reference is on disk) */ |
228 | 0 | dt->shared->u.atomic.u.r.file = file; |
229 | | |
230 | | /* dt now owns a reference to file */ |
231 | 0 | 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 | 0 | if (dt->shared->u.atomic.u.r.rtype == H5R_OBJECT1) { |
235 | 0 | 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 | 0 | 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 | 0 | dt->shared->size = H5T_REF_OBJ_DISK_SIZE(f); |
257 | 0 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
258 | | |
259 | | /* Set up the function pointers to access the reference in memory */ |
260 | 0 | dt->shared->u.atomic.u.r.cls = &H5T_ref_obj_disk_g; |
261 | 0 | } /* end if */ |
262 | 0 | else if (dt->shared->u.atomic.u.r.rtype == H5R_DATASET_REGION1) { |
263 | 0 | 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 | 0 | 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 | 0 | dt->shared->size = H5T_REF_DSETREG_DISK_SIZE(f); |
285 | 0 | dt->shared->u.atomic.prec = 8 * dt->shared->size; |
286 | | |
287 | | /* Set up the function pointers to access the reference in memory */ |
288 | 0 | dt->shared->u.atomic.u.r.cls = &H5T_ref_dsetreg_disk_g; |
289 | 0 | } /* 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 | 0 | break; |
323 | | |
324 | 0 | 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 | 3 | } /* end switch */ |
342 | | |
343 | | /* Indicate that the location changed */ |
344 | 3 | ret_value = true; |
345 | | |
346 | 3 | done: |
347 | 3 | FUNC_LEAVE_NOAPI(ret_value) |
348 | 3 | } /* 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 *dst_ref = (H5R_ref_priv_t *)dst_buf; |
647 | 0 | H5R_ref_priv_t tmp_ref; /* Temporary reference to decode into */ |
648 | 0 | herr_t ret_value = SUCCEED; |
649 | |
|
650 | 0 | FUNC_ENTER_PACKAGE |
651 | 0 | H5T_REF_LOG_DEBUG(""); |
652 | | |
653 | | /* Sanity check */ |
654 | 0 | assert(src_buf); |
655 | 0 | assert(src_size); |
656 | 0 | assert(dst_buf); |
657 | 0 | assert(dst_size == H5T_REF_MEM_SIZE); |
658 | 0 | HDcompile_assert(sizeof(*dst_ref) == sizeof(tmp_ref)); |
659 | | |
660 | | /* Memory-to-memory conversion to support vlen conversion */ |
661 | 0 | if (NULL == src_file) { |
662 | 0 | H5MM_memcpy(dst_buf, src_buf, src_size); |
663 | 0 | HGOTO_DONE(ret_value); |
664 | 0 | } |
665 | | |
666 | | #ifndef NDEBUG |
667 | | if ((src_type == H5R_OBJECT1) || (src_type == H5R_DATASET_REGION1)) { |
668 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
669 | | |
670 | | /* Check if using native VOL connector */ |
671 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
672 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector"); |
673 | | |
674 | | /* Must use native VOL connector for this operation */ |
675 | | assert(is_native); |
676 | | } |
677 | | #endif /* NDEBUG */ |
678 | | |
679 | | /* Retrieve file from VOL object */ |
680 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
681 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
682 | | |
683 | | /* Make sure reference buffer is correctly initialized */ |
684 | 0 | memset(&tmp_ref, 0, sizeof(tmp_ref)); |
685 | |
|
686 | 0 | switch (src_type) { |
687 | 0 | case H5R_OBJECT1: { |
688 | 0 | size_t token_size = H5F_SIZEOF_ADDR(src_f); |
689 | |
|
690 | 0 | if (H5R__create_object((const H5O_token_t *)src_buf, token_size, &tmp_ref) < 0) |
691 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create object reference"); |
692 | 0 | } break; |
693 | | |
694 | 0 | case H5R_DATASET_REGION1: { |
695 | 0 | const struct H5Tref_dsetreg *src_reg = (const struct H5Tref_dsetreg *)src_buf; |
696 | 0 | size_t token_size = H5F_SIZEOF_ADDR(src_f); |
697 | |
|
698 | 0 | if (H5R__create_region(&src_reg->token, token_size, src_reg->space, &tmp_ref) < 0) |
699 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create region reference"); |
700 | | |
701 | | /* create_region creates its internal copy of the space */ |
702 | 0 | if (H5S_close(src_reg->space) < 0) |
703 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "Cannot close dataspace"); |
704 | 0 | } break; |
705 | | |
706 | 0 | case H5R_DATASET_REGION2: |
707 | | /* Pass the correct encoding version for the selection depending on the |
708 | | * file libver bounds, this is later retrieved in H5S hyper decode */ |
709 | 0 | H5CX_set_libver_bounds(src_f); |
710 | | /* FALLTHROUGH */ |
711 | 0 | H5_ATTR_FALLTHROUGH |
712 | 0 | case H5R_OBJECT2: |
713 | 0 | case H5R_ATTR: |
714 | | /* Decode reference */ |
715 | 0 | if (H5R__decode((const unsigned char *)src_buf, &src_size, &tmp_ref) < 0) |
716 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "Cannot decode reference"); |
717 | 0 | break; |
718 | | |
719 | 0 | case H5R_BADTYPE: |
720 | 0 | case H5R_MAXTYPE: |
721 | 0 | default: |
722 | 0 | assert("unknown reference type" && 0); |
723 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)"); |
724 | 0 | } /* end switch */ |
725 | | |
726 | | /* If no filename set, this is not an external reference */ |
727 | 0 | if (NULL == H5R_REF_FILENAME(&tmp_ref)) { |
728 | | /* TODO temporary hack to retrieve file object */ |
729 | 0 | if ((file_id = H5F_get_file_id(src_file, H5I_FILE, false)) < 0) |
730 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); |
731 | | |
732 | | /* Attach loc ID to reference and hold reference to it, this is a |
733 | | * user exposed reference so set app_ref to true. */ |
734 | 0 | if (H5R__set_loc_id(&tmp_ref, file_id, true, true) < 0) |
735 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTSET, FAIL, "unable to attach location id to reference"); |
736 | 0 | } /* end if */ |
737 | | |
738 | | /* Set output info */ |
739 | 0 | H5MM_memcpy(dst_ref, &tmp_ref, sizeof(tmp_ref)); |
740 | |
|
741 | 0 | done: |
742 | 0 | if ((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) |
743 | 0 | HDONE_ERROR(H5E_REFERENCE, H5E_CANTDEC, FAIL, "unable to decrement refcount on location id"); |
744 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
745 | 0 | } /* end H5T__ref_mem_write() */ |
746 | | |
747 | | /*------------------------------------------------------------------------- |
748 | | * Function: H5T__ref_disk_isnull |
749 | | * |
750 | | * Purpose: Check if it's a NULL / uninitialized reference. |
751 | | * |
752 | | * Return: Non-negative on success/Negative on failure |
753 | | * |
754 | | *------------------------------------------------------------------------- |
755 | | */ |
756 | | /* |
757 | | * It is the correct thing to do to have the reference buffer |
758 | | * be const-qualified here, but the VOL "blob specific" routine |
759 | | * needs a non-const pointer since an operation might modify |
760 | | * the "blob". Disable this warning here (at least temporarily) |
761 | | * for this reason. |
762 | | */ |
763 | | H5_WARN_CAST_AWAY_CONST_OFF |
764 | | static herr_t |
765 | | H5T__ref_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, bool *isnull) |
766 | 0 | { |
767 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
768 | 0 | H5R_type_t ref_type; |
769 | 0 | herr_t ret_value = SUCCEED; |
770 | |
|
771 | 0 | FUNC_ENTER_PACKAGE |
772 | 0 | H5T_REF_LOG_DEBUG(""); |
773 | | |
774 | | /* Check parameters */ |
775 | 0 | assert(src_file); |
776 | 0 | assert(src_buf); |
777 | 0 | assert(isnull); |
778 | | |
779 | | /* Try to check encoded reference type */ |
780 | 0 | ref_type = (H5R_type_t)*p++; |
781 | 0 | if (ref_type) { |
782 | | /* This is a valid reference */ |
783 | 0 | *isnull = false; |
784 | 0 | } |
785 | 0 | else { |
786 | 0 | H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ |
787 | | |
788 | | /* Skip the size / header */ |
789 | 0 | p = (const uint8_t *)src_buf + H5R_ENCODE_HEADER_SIZE + sizeof(uint32_t); |
790 | | |
791 | | /* Set up VOL callback arguments */ |
792 | 0 | vol_cb_args.op_type = H5VL_BLOB_ISNULL; |
793 | 0 | vol_cb_args.args.is_null.isnull = isnull; |
794 | | |
795 | | /* Check if blob ID is "nil" */ |
796 | 0 | if (H5VL_blob_specific(src_file, (void *)p, &vol_cb_args) < 0) |
797 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'"); |
798 | 0 | } |
799 | | |
800 | 0 | done: |
801 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
802 | 0 | } /* end H5T__ref_disk_isnull() */ |
803 | | H5_WARN_CAST_AWAY_CONST_ON |
804 | | |
805 | | /*------------------------------------------------------------------------- |
806 | | * Function: H5T__ref_disk_setnull |
807 | | * |
808 | | * Purpose: Set a reference as NULL / uninitialized. |
809 | | * |
810 | | * Return: Non-negative on success/Negative on failure |
811 | | * |
812 | | *------------------------------------------------------------------------- |
813 | | */ |
814 | | static herr_t |
815 | | H5T__ref_disk_setnull(H5VL_object_t *dst_file, void *dst_buf, void *bg_buf) |
816 | 0 | { |
817 | 0 | H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ |
818 | 0 | uint8_t *q = (uint8_t *)dst_buf; |
819 | 0 | uint8_t *p_bg = (uint8_t *)bg_buf; |
820 | 0 | herr_t ret_value = SUCCEED; |
821 | |
|
822 | 0 | FUNC_ENTER_PACKAGE |
823 | 0 | H5T_REF_LOG_DEBUG(""); |
824 | |
|
825 | 0 | assert(dst_file); |
826 | 0 | assert(dst_buf); |
827 | | |
828 | | /* TODO Should get rid of bg stuff */ |
829 | 0 | if (p_bg) { |
830 | | /* Skip the size / header */ |
831 | 0 | p_bg += (sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE); |
832 | | |
833 | | /* Set up VOL callback arguments */ |
834 | 0 | vol_cb_args.op_type = H5VL_BLOB_DELETE; |
835 | | |
836 | | /* Remove blob for old data */ |
837 | 0 | if (H5VL_blob_specific(dst_file, (void *)p_bg, &vol_cb_args) < 0) |
838 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob"); |
839 | 0 | } /* end if */ |
840 | | |
841 | | /* Copy header manually so that it does not get encoded into the blob */ |
842 | 0 | memset(q, 0, H5R_ENCODE_HEADER_SIZE); |
843 | 0 | q += H5R_ENCODE_HEADER_SIZE; |
844 | | |
845 | | /* Set the size */ |
846 | 0 | UINT32ENCODE(q, 0); |
847 | | |
848 | | /* Set up VOL callback arguments */ |
849 | 0 | vol_cb_args.op_type = H5VL_BLOB_SETNULL; |
850 | | |
851 | | /* Set blob ID to "nil" */ |
852 | 0 | if (H5VL_blob_specific(dst_file, q, &vol_cb_args) < 0) |
853 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'"); |
854 | | |
855 | 0 | done: |
856 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
857 | 0 | } /* end H5T__ref_disk_setnull() */ |
858 | | |
859 | | /*------------------------------------------------------------------------- |
860 | | * Function: H5T__ref_disk_getsize |
861 | | * |
862 | | * Purpose: Retrieves the length of a disk based reference. |
863 | | * |
864 | | * Return: Non-negative value (cannot fail) |
865 | | * |
866 | | *------------------------------------------------------------------------- |
867 | | */ |
868 | | static size_t |
869 | | H5T__ref_disk_getsize(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, size_t src_size, |
870 | | H5VL_object_t H5_ATTR_UNUSED *dst_file, bool *dst_copy) |
871 | 0 | { |
872 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
873 | 0 | unsigned flags; |
874 | 0 | H5R_type_t ref_type; |
875 | 0 | size_t ret_value = 0; |
876 | |
|
877 | 0 | FUNC_ENTER_PACKAGE |
878 | 0 | H5T_REF_LOG_DEBUG(""); |
879 | |
|
880 | 0 | assert(src_buf); |
881 | | |
882 | | /* Set reference type */ |
883 | 0 | ref_type = (H5R_type_t)*p++; |
884 | 0 | if (ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) |
885 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, 0, "invalid reference type"); |
886 | | |
887 | | /* Set flags */ |
888 | 0 | flags = (unsigned)*p++; |
889 | |
|
890 | 0 | if (!(flags & H5R_IS_EXTERNAL) && (ref_type == H5R_OBJECT2)) { |
891 | | /* Can do a direct copy and skip blob decoding */ |
892 | 0 | *dst_copy = true; |
893 | |
|
894 | 0 | ret_value = src_size; |
895 | 0 | } /* end if */ |
896 | 0 | else { |
897 | | /* Retrieve encoded data size */ |
898 | 0 | UINT32DECODE(p, ret_value); |
899 | | |
900 | | /* Add size of the header */ |
901 | 0 | ret_value += H5R_ENCODE_HEADER_SIZE; |
902 | 0 | } /* end else */ |
903 | |
|
904 | 0 | done: |
905 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
906 | 0 | } /* end H5T__ref_disk_getsize() */ |
907 | | |
908 | | /*------------------------------------------------------------------------- |
909 | | * Function: H5T__ref_disk_read |
910 | | * |
911 | | * Purpose: Reads the disk based reference into a buffer |
912 | | * |
913 | | * Return: Non-negative on success/Negative on failure |
914 | | * |
915 | | *------------------------------------------------------------------------- |
916 | | */ |
917 | | static herr_t |
918 | | H5T__ref_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t H5_ATTR_NDEBUG_UNUSED src_size, |
919 | | H5VL_object_t H5_ATTR_UNUSED *dst_file, void *dst_buf, size_t dst_size) |
920 | 0 | { |
921 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
922 | 0 | uint8_t *q = (uint8_t *)dst_buf; |
923 | 0 | size_t blob_size = dst_size; |
924 | 0 | herr_t ret_value = SUCCEED; |
925 | |
|
926 | 0 | FUNC_ENTER_PACKAGE |
927 | 0 | H5T_REF_LOG_DEBUG(""); |
928 | |
|
929 | 0 | assert(src_file); |
930 | 0 | assert(src_buf); |
931 | 0 | assert(dst_buf); |
932 | 0 | assert(dst_size); |
933 | | |
934 | | /* Copy header manually */ |
935 | 0 | H5MM_memcpy(q, p, H5R_ENCODE_HEADER_SIZE); |
936 | 0 | p += H5R_ENCODE_HEADER_SIZE; |
937 | 0 | q += H5R_ENCODE_HEADER_SIZE; |
938 | 0 | blob_size -= H5R_ENCODE_HEADER_SIZE; |
939 | | |
940 | | /* Skip the size */ |
941 | 0 | p += sizeof(uint32_t); |
942 | 0 | assert(src_size > (H5R_ENCODE_HEADER_SIZE + sizeof(uint32_t))); |
943 | | |
944 | | /* Retrieve blob */ |
945 | 0 | if (H5VL_blob_get(src_file, p, q, blob_size, NULL) < 0) |
946 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get blob"); |
947 | | |
948 | 0 | done: |
949 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
950 | 0 | } /* end H5T__ref_disk_read() */ |
951 | | |
952 | | /*------------------------------------------------------------------------- |
953 | | * Function: H5T__ref_disk_write |
954 | | * |
955 | | * Purpose: Writes the disk based reference from a buffer |
956 | | * |
957 | | * Return: Non-negative on success/Negative on failure |
958 | | * |
959 | | *------------------------------------------------------------------------- |
960 | | */ |
961 | | static herr_t |
962 | | H5T__ref_disk_write(H5VL_object_t H5_ATTR_UNUSED *src_file, const void *src_buf, size_t src_size, |
963 | | H5R_type_t H5_ATTR_UNUSED src_type, H5VL_object_t *dst_file, void *dst_buf, |
964 | | size_t H5_ATTR_NDEBUG_UNUSED dst_size, void *bg_buf) |
965 | 0 | { |
966 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
967 | 0 | uint8_t *q = (uint8_t *)dst_buf; |
968 | 0 | uint8_t *p_bg = (uint8_t *)bg_buf; |
969 | 0 | herr_t ret_value = SUCCEED; |
970 | |
|
971 | 0 | FUNC_ENTER_PACKAGE |
972 | 0 | H5T_REF_LOG_DEBUG(""); |
973 | |
|
974 | 0 | assert(src_buf); |
975 | 0 | assert(src_size); |
976 | 0 | assert(dst_file); |
977 | 0 | assert(dst_buf); |
978 | | |
979 | | /* TODO Should get rid of bg stuff */ |
980 | 0 | if (p_bg) { |
981 | 0 | H5VL_blob_specific_args_t vol_cb_args; /* Arguments to VOL callback */ |
982 | | |
983 | | /* Skip the size / header */ |
984 | 0 | p_bg += (sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE); |
985 | |
|
986 | | #ifndef NDEBUG |
987 | | size_t p_buf_size_left = dst_size; |
988 | | assert(p_buf_size_left > (sizeof(uint32_t) + H5R_ENCODE_HEADER_SIZE)); |
989 | | #endif |
990 | | |
991 | | /* Set up VOL callback arguments */ |
992 | 0 | vol_cb_args.op_type = H5VL_BLOB_DELETE; |
993 | | |
994 | | /* Remove blob for old data */ |
995 | 0 | if (H5VL_blob_specific(dst_file, (void *)p_bg, &vol_cb_args) < 0) |
996 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob"); |
997 | 0 | } /* end if */ |
998 | | |
999 | | /* Copy header manually so that it does not get encoded into the blob */ |
1000 | 0 | H5MM_memcpy(q, p, H5R_ENCODE_HEADER_SIZE); |
1001 | 0 | p += H5R_ENCODE_HEADER_SIZE; |
1002 | 0 | q += H5R_ENCODE_HEADER_SIZE; |
1003 | 0 | src_size -= H5R_ENCODE_HEADER_SIZE; |
1004 | |
|
1005 | | #ifndef NDEBUG |
1006 | | { |
1007 | | size_t buf_size_left = dst_size - sizeof(uint32_t); |
1008 | | assert(buf_size_left > sizeof(uint32_t)); |
1009 | | } |
1010 | | #endif |
1011 | | |
1012 | | /* Set the size */ |
1013 | 0 | UINT32ENCODE(q, src_size); |
1014 | | |
1015 | | /* Store blob */ |
1016 | 0 | if (H5VL_blob_put(dst_file, p, src_size, q, NULL) < 0) |
1017 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to put blob"); |
1018 | | |
1019 | 0 | done: |
1020 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1021 | 0 | } /* end H5T__ref_disk_write() */ |
1022 | | |
1023 | | /*------------------------------------------------------------------------- |
1024 | | * Function: H5T__ref_obj_disk_isnull |
1025 | | * |
1026 | | * Purpose: Check if it's a NULL / uninitialized reference. |
1027 | | * |
1028 | | * Return: Non-negative on success/Negative on failure |
1029 | | * |
1030 | | *------------------------------------------------------------------------- |
1031 | | */ |
1032 | | static herr_t |
1033 | | H5T__ref_obj_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, bool *isnull) |
1034 | 0 | { |
1035 | 0 | H5F_t *src_f; |
1036 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
1037 | 0 | haddr_t addr; |
1038 | 0 | herr_t ret_value = SUCCEED; |
1039 | |
|
1040 | 0 | FUNC_ENTER_PACKAGE |
1041 | 0 | H5T_REF_LOG_DEBUG(""); |
1042 | | |
1043 | | /* Check parameters */ |
1044 | 0 | assert(src_file); |
1045 | 0 | assert(src_buf); |
1046 | 0 | assert(isnull); |
1047 | |
|
1048 | | #ifndef NDEBUG |
1049 | | { |
1050 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1051 | | |
1052 | | /* Check if using native VOL connector */ |
1053 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1054 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector"); |
1055 | | |
1056 | | /* Must use native VOL connector for this operation */ |
1057 | | assert(is_native); |
1058 | | } |
1059 | | #endif /* NDEBUG */ |
1060 | | |
1061 | | /* Retrieve file from VOL object */ |
1062 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1063 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
1064 | | |
1065 | | /* Get the object address */ |
1066 | 0 | H5F_addr_decode(src_f, &p, &addr); |
1067 | | |
1068 | | /* Check if heap address is 'nil' */ |
1069 | 0 | *isnull = (addr == 0) ? true : false; |
1070 | |
|
1071 | 0 | done: |
1072 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1073 | 0 | } /* end H5T__ref_obj_disk_isnull() */ |
1074 | | |
1075 | | /*------------------------------------------------------------------------- |
1076 | | * Function: H5T__ref_obj_disk_getsize |
1077 | | * |
1078 | | * Purpose: Retrieves the length of a disk based reference. |
1079 | | * |
1080 | | * Return: Non-negative value (cannot fail) |
1081 | | * |
1082 | | *------------------------------------------------------------------------- |
1083 | | */ |
1084 | | static size_t |
1085 | | H5T__ref_obj_disk_getsize(H5VL_object_t *src_file, const void H5_ATTR_UNUSED *src_buf, |
1086 | | size_t H5_ATTR_UNUSED src_size, H5VL_object_t H5_ATTR_UNUSED *dst_file, |
1087 | | bool H5_ATTR_UNUSED *dst_copy) |
1088 | 0 | { |
1089 | 0 | H5F_t *src_f; |
1090 | 0 | size_t ret_value = 0; |
1091 | |
|
1092 | 0 | FUNC_ENTER_PACKAGE |
1093 | 0 | H5T_REF_LOG_DEBUG(""); |
1094 | |
|
1095 | 0 | assert(src_file); |
1096 | 0 | assert(src_buf); |
1097 | |
|
1098 | | #ifndef NDEBUG |
1099 | | { |
1100 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1101 | | |
1102 | | /* Check if using native VOL connector */ |
1103 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1104 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't query if file uses native VOL connector"); |
1105 | | |
1106 | | /* Must use native VOL connector for this operation */ |
1107 | | assert(is_native); |
1108 | | } |
1109 | | #endif /* NDEBUG */ |
1110 | | |
1111 | | /* Retrieve file from VOL object */ |
1112 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1113 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid VOL object"); |
1114 | | |
1115 | 0 | assert(src_size == H5T_REF_OBJ_DISK_SIZE(src_f)); |
1116 | |
|
1117 | 0 | ret_value = H5T_REF_OBJ_DISK_SIZE(src_f); |
1118 | |
|
1119 | 0 | done: |
1120 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1121 | 0 | } /* end H5T__ref_obj_disk_getsize() */ |
1122 | | |
1123 | | /*------------------------------------------------------------------------- |
1124 | | * Function: H5T__ref_obj_disk_read |
1125 | | * |
1126 | | * Purpose: Reads the disk based reference into a buffer |
1127 | | * |
1128 | | * Return: Non-negative on success/Negative on failure |
1129 | | * |
1130 | | *------------------------------------------------------------------------- |
1131 | | */ |
1132 | | static herr_t |
1133 | | H5T__ref_obj_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
1134 | | H5VL_object_t H5_ATTR_UNUSED *dst_file, void *dst_buf, size_t H5_ATTR_UNUSED dst_size) |
1135 | 0 | { |
1136 | 0 | H5F_t *src_f; |
1137 | 0 | herr_t ret_value = SUCCEED; |
1138 | |
|
1139 | 0 | FUNC_ENTER_PACKAGE |
1140 | 0 | H5T_REF_LOG_DEBUG(""); |
1141 | |
|
1142 | 0 | assert(src_file); |
1143 | 0 | assert(src_buf); |
1144 | 0 | assert(dst_buf); |
1145 | |
|
1146 | | #ifndef NDEBUG |
1147 | | { |
1148 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1149 | | |
1150 | | /* Check if using native VOL connector */ |
1151 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1152 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector"); |
1153 | | |
1154 | | /* Must use native VOL connector for this operation */ |
1155 | | assert(is_native); |
1156 | | } |
1157 | | #endif /* NDEBUG */ |
1158 | | |
1159 | | /* Retrieve file from VOL object */ |
1160 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1161 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
1162 | | |
1163 | 0 | assert(src_size == H5T_REF_OBJ_DISK_SIZE(src_f)); |
1164 | 0 | assert(dst_size == H5F_SIZEOF_ADDR(src_f)); |
1165 | | |
1166 | | /* Get object address */ |
1167 | 0 | if (H5R__decode_token_obj_compat((const unsigned char *)src_buf, &src_size, (H5O_token_t *)dst_buf, |
1168 | 0 | H5F_SIZEOF_ADDR(src_f)) < 0) |
1169 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address"); |
1170 | | |
1171 | 0 | done: |
1172 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1173 | 0 | } /* end H5T__ref_obj_disk_read() */ |
1174 | | |
1175 | | /*------------------------------------------------------------------------- |
1176 | | * Function: H5T__ref_dsetreg_disk_isnull |
1177 | | * |
1178 | | * Purpose: Check if it's a NULL / uninitialized reference. |
1179 | | * |
1180 | | * Return: Non-negative on success/Negative on failure |
1181 | | * |
1182 | | *------------------------------------------------------------------------- |
1183 | | */ |
1184 | | static herr_t |
1185 | | H5T__ref_dsetreg_disk_isnull(const H5VL_object_t *src_file, const void *src_buf, bool *isnull) |
1186 | 0 | { |
1187 | 0 | H5F_t *src_f; |
1188 | 0 | const uint8_t *p = (const uint8_t *)src_buf; |
1189 | 0 | haddr_t addr; |
1190 | 0 | herr_t ret_value = SUCCEED; |
1191 | |
|
1192 | 0 | FUNC_ENTER_PACKAGE |
1193 | 0 | H5T_REF_LOG_DEBUG(""); |
1194 | | |
1195 | | /* Check parameters */ |
1196 | 0 | assert(src_file); |
1197 | 0 | assert(src_buf); |
1198 | 0 | assert(isnull); |
1199 | |
|
1200 | | #ifndef NDEBUG |
1201 | | { |
1202 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1203 | | |
1204 | | /* Check if using native VOL connector */ |
1205 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1206 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector"); |
1207 | | |
1208 | | /* Must use native VOL connector for this operation */ |
1209 | | assert(is_native); |
1210 | | } |
1211 | | #endif /* NDEBUG */ |
1212 | | |
1213 | | /* Retrieve file from VOL object */ |
1214 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1215 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
1216 | | |
1217 | | /* Get the heap address */ |
1218 | 0 | H5F_addr_decode(src_f, &p, &addr); |
1219 | | |
1220 | | /* Check if heap address is 'nil' */ |
1221 | 0 | *isnull = (addr == 0) ? true : false; |
1222 | |
|
1223 | 0 | done: |
1224 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1225 | 0 | } /* end H5T__ref_dsetreg_disk_isnull() */ |
1226 | | |
1227 | | /*------------------------------------------------------------------------- |
1228 | | * Function: H5T__ref_dsetreg_disk_getsize |
1229 | | * |
1230 | | * Purpose: Retrieves the length of a disk based reference. |
1231 | | * |
1232 | | * Return: Non-negative value (cannot fail) |
1233 | | * |
1234 | | *------------------------------------------------------------------------- |
1235 | | */ |
1236 | | static size_t |
1237 | | H5T__ref_dsetreg_disk_getsize(H5VL_object_t H5_ATTR_UNUSED *src_file, const void H5_ATTR_UNUSED *src_buf, |
1238 | | size_t H5_ATTR_UNUSED src_size, H5VL_object_t H5_ATTR_UNUSED *dst_file, |
1239 | | bool H5_ATTR_UNUSED *dst_copy) |
1240 | 0 | { |
1241 | 0 | size_t ret_value = sizeof(struct H5Tref_dsetreg); |
1242 | |
|
1243 | | #ifndef NDEBUG |
1244 | | FUNC_ENTER_PACKAGE |
1245 | | #else |
1246 | 0 | FUNC_ENTER_PACKAGE_NOERR |
1247 | 0 | #endif |
1248 | 0 | H5T_REF_LOG_DEBUG(""); |
1249 | |
|
1250 | 0 | assert(src_buf); |
1251 | |
|
1252 | | #ifndef NDEBUG |
1253 | | { |
1254 | | H5F_t *src_f; |
1255 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1256 | | |
1257 | | /* Check if using native VOL connector */ |
1258 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1259 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, 0, "can't query if file uses native VOL connector"); |
1260 | | |
1261 | | /* Must use native VOL connector for this operation */ |
1262 | | assert(is_native); |
1263 | | |
1264 | | /* Retrieve file from VOL object */ |
1265 | | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1266 | | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid VOL object"); |
1267 | | |
1268 | | assert(src_size == H5T_REF_DSETREG_DISK_SIZE(src_f)); |
1269 | | } |
1270 | | #endif /* NDEBUG */ |
1271 | |
|
1272 | | #ifndef NDEBUG |
1273 | | done: |
1274 | | #endif |
1275 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1276 | 0 | } /* end H5T__ref_dsetreg_disk_getsize() */ |
1277 | | |
1278 | | /*------------------------------------------------------------------------- |
1279 | | * Function: H5T__ref_dsetreg_disk_read |
1280 | | * |
1281 | | * Purpose: Reads the disk based reference into a buffer |
1282 | | * |
1283 | | * Return: Non-negative on success/Negative on failure |
1284 | | * |
1285 | | *------------------------------------------------------------------------- |
1286 | | */ |
1287 | | static herr_t |
1288 | | H5T__ref_dsetreg_disk_read(H5VL_object_t *src_file, const void *src_buf, size_t src_size, |
1289 | | H5VL_object_t H5_ATTR_UNUSED *dst_file, void *dst_buf, |
1290 | | size_t H5_ATTR_UNUSED dst_size) |
1291 | 0 | { |
1292 | 0 | H5F_t *src_f; |
1293 | 0 | struct H5Tref_dsetreg *dst_reg = (struct H5Tref_dsetreg *)dst_buf; |
1294 | 0 | herr_t ret_value = SUCCEED; |
1295 | |
|
1296 | 0 | FUNC_ENTER_PACKAGE |
1297 | 0 | H5T_REF_LOG_DEBUG(""); |
1298 | |
|
1299 | 0 | assert(src_file); |
1300 | 0 | assert(src_buf); |
1301 | 0 | assert(dst_buf); |
1302 | 0 | assert(dst_size == sizeof(struct H5Tref_dsetreg)); |
1303 | |
|
1304 | | #ifndef NDEBUG |
1305 | | { |
1306 | | bool is_native = false; /* Whether the src file is using the native VOL connector */ |
1307 | | |
1308 | | /* Check if using native VOL connector */ |
1309 | | if (H5VL_object_is_native(src_file, &is_native) < 0) |
1310 | | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't query if file uses native VOL connector"); |
1311 | | |
1312 | | /* Must use native VOL connector for this operation */ |
1313 | | assert(is_native); |
1314 | | } |
1315 | | #endif /* NDEBUG */ |
1316 | | |
1317 | | /* Retrieve file from VOL object */ |
1318 | 0 | if (NULL == (src_f = (H5F_t *)H5VL_object_data(src_file))) |
1319 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid VOL object"); |
1320 | | |
1321 | 0 | assert(src_size == H5T_REF_DSETREG_DISK_SIZE(src_f)); |
1322 | | |
1323 | | /* Retrieve object address and space */ |
1324 | 0 | if (H5R__decode_token_region_compat(src_f, (const unsigned char *)src_buf, &src_size, &dst_reg->token, |
1325 | 0 | H5F_SIZEOF_ADDR(src_f), &dst_reg->space) < 0) |
1326 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, FAIL, "unable to get object address"); |
1327 | | |
1328 | 0 | done: |
1329 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1330 | 0 | } /* end H5T__ref_dsetreg_disk_read() */ |
1331 | | |
1332 | | /*------------------------------------------------------------------------- |
1333 | | * Function: H5T__ref_reclaim |
1334 | | * |
1335 | | * Purpose: Internal routine to free reference datatypes |
1336 | | * |
1337 | | * Return: Non-negative on success / Negative on failure |
1338 | | * |
1339 | | *------------------------------------------------------------------------- |
1340 | | */ |
1341 | | herr_t |
1342 | | H5T__ref_reclaim(void *elem, const H5T_t *dt) |
1343 | 0 | { |
1344 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
1345 | |
|
1346 | 0 | FUNC_ENTER_PACKAGE |
1347 | 0 | H5T_REF_LOG_DEBUG(""); |
1348 | | |
1349 | | /* Sanity checks */ |
1350 | 0 | assert(elem); |
1351 | 0 | assert(dt && (dt->shared->type == H5T_REFERENCE)); |
1352 | |
|
1353 | 0 | if (dt->shared->u.atomic.u.r.opaque && H5R__destroy((H5R_ref_priv_t *)elem) < 0) |
1354 | 0 | HGOTO_ERROR(H5E_REFERENCE, H5E_CANTFREE, FAIL, "cannot free reference"); |
1355 | | |
1356 | 0 | done: |
1357 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1358 | 0 | } /* end H5T__ref_reclaim() */ |