Coverage Report

Created: 2025-11-11 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5Ocopy_ref.c
Line
Count
Source
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*-------------------------------------------------------------------------
14
 *
15
 * Created:     H5Ocopy_ref.c
16
 *
17
 * Purpose:     Object with references copying routines
18
 *
19
 *-------------------------------------------------------------------------
20
 */
21
22
/****************/
23
/* Module Setup */
24
/****************/
25
26
#include "H5Omodule.h" /* This source code file is part of the H5O module */
27
#define H5R_FRIEND     /* Suppress error about including H5Rpkg   */
28
29
/***********/
30
/* Headers */
31
/***********/
32
#include "H5private.h"   /* Generic Functions                        */
33
#include "H5Eprivate.h"  /* Error handling                           */
34
#include "H5Fprivate.h"  /* File                                     */
35
#include "H5FLprivate.h" /* Free Lists                               */
36
#include "H5Iprivate.h"  /* IDs                                      */
37
#include "H5Lprivate.h"  /* Links                                    */
38
#include "H5MMprivate.h" /* Memory management                        */
39
#include "H5Opkg.h"      /* Object headers                           */
40
#include "H5Rpkg.h"      /* References                               */
41
42
#include "H5VLnative_private.h" /* Native VOL connector                     */
43
44
/****************/
45
/* Local Macros */
46
/****************/
47
48
/******************/
49
/* Local Typedefs */
50
/******************/
51
52
/********************/
53
/* Package Typedefs */
54
/********************/
55
56
/********************/
57
/* Local Prototypes */
58
/********************/
59
60
static herr_t H5O__copy_obj_by_ref(H5O_loc_t *src_oloc, H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc,
61
                                   H5O_copy_t *cpy_info);
62
static herr_t H5O__copy_expand_ref_object1(H5O_loc_t *src_oloc, const void *buf_src, H5O_loc_t *dst_oloc,
63
                                           H5G_loc_t *dst_root_loc, void *buf_dst, size_t ref_count,
64
                                           H5O_copy_t *cpy_info);
65
static herr_t H5O__copy_expand_ref_region1(H5O_loc_t *src_oloc, const void *buf_src, H5O_loc_t *dst_oloc,
66
                                           H5G_loc_t *dst_root_loc, void *buf_dst, size_t ref_count,
67
                                           H5O_copy_t *cpy_info);
68
static herr_t H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, const H5T_t *dt_src, const void *buf_src,
69
                                           size_t nbytes_src, H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc,
70
                                           void *buf_dst, size_t ref_count, H5O_copy_t *cpy_info);
71
72
/*********************/
73
/* Package Variables */
74
/*********************/
75
76
/* Declare extern the free list to manage blocks of type conversion data */
77
H5FL_BLK_EXTERN(type_conv);
78
79
/*****************************/
80
/* Library Private Variables */
81
/*****************************/
82
83
/*******************/
84
/* Local Variables */
85
/*******************/
86
87
/*-------------------------------------------------------------------------
88
 * Function:    H5O__copy_obj_by_ref
89
 *
90
 * Purpose:     Copy the object pointed to by src_oloc.
91
 *
92
 * Return:      Non-negative on success/Negative on failure
93
 *
94
 *-------------------------------------------------------------------------
95
 */
96
static herr_t
97
H5O__copy_obj_by_ref(H5O_loc_t *src_oloc, H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info)
98
0
{
99
0
    herr_t ret_value = SUCCEED;
100
101
0
    FUNC_ENTER_PACKAGE
102
103
0
    assert(src_oloc);
104
0
    assert(dst_oloc);
105
106
    /* Perform the copy, or look up existing copy */
107
0
    if ((ret_value = H5O_copy_header_map(src_oloc, dst_oloc, cpy_info, false, NULL, NULL)) < 0)
108
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object");
109
110
    /* Check if a new valid object is copied to the destination */
111
0
    if (H5_addr_defined(dst_oloc->addr) && (ret_value > SUCCEED)) {
112
0
        char       tmp_obj_name[80];
113
0
        H5G_name_t new_path;
114
0
        H5O_loc_t  new_oloc;
115
0
        H5G_loc_t  new_loc;
116
117
        /* Set up group location for new object */
118
0
        new_loc.oloc = &new_oloc;
119
0
        new_loc.path = &new_path;
120
0
        H5G_loc_reset(&new_loc);
121
0
        new_oloc.file = dst_oloc->file;
122
0
        new_oloc.addr = dst_oloc->addr;
123
124
        /* Pick a default name for the new object */
125
0
        snprintf(tmp_obj_name, sizeof(tmp_obj_name), "~obj_pointed_by_%llu",
126
0
                 (unsigned long long)dst_oloc->addr);
127
128
        /* Create a link to the newly copied object */
129
        /* Note: since H5O_copy_header_map actually copied the target object, it
130
         * must exist either in cache or on disk, therefore it is safe to not
131
         * pass the obj_type and udata fields returned by H5O_copy_header_map.
132
         * This could be changed in the future to slightly improve performance
133
         * --NAF */
134
0
        if (H5L_link(dst_root_loc, tmp_obj_name, &new_loc, cpy_info->lcpl_id) < 0)
135
0
            HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link");
136
137
0
        H5G_loc_free(&new_loc);
138
0
    } /* if (H5_addr_defined(dst_oloc.addr)) */
139
140
0
done:
141
0
    FUNC_LEAVE_NOAPI(ret_value)
142
0
} /* end H5O__copy_obj_by_ref() */
143
144
/*-------------------------------------------------------------------------
145
 * Function:    H5O__copy_expand_ref_object1
146
 *
147
 * Purpose: Copy the object pointed by a deprecated object reference.
148
 *
149
 * Return:  Non-negative on success/Negative on failure
150
 *
151
 *-------------------------------------------------------------------------
152
 */
153
static herr_t
154
H5O__copy_expand_ref_object1(H5O_loc_t *src_oloc, const void *buf_src, H5O_loc_t *dst_oloc,
155
                             H5G_loc_t *dst_root_loc, void *buf_dst, size_t ref_count, H5O_copy_t *cpy_info)
156
0
{
157
0
    const hobj_ref_t   *src_ref                     = (const hobj_ref_t *)buf_src;
158
0
    hobj_ref_t         *dst_ref                     = (hobj_ref_t *)buf_dst;
159
0
    const unsigned char zeros[H5R_OBJ_REF_BUF_SIZE] = {0};
160
0
    size_t              buf_size                    = H5R_OBJ_REF_BUF_SIZE;
161
0
    size_t              i; /* Local index variable */
162
0
    size_t              token_size = H5F_SIZEOF_ADDR(src_oloc->file);
163
0
    herr_t              ret_value  = SUCCEED;
164
165
0
    FUNC_ENTER_PACKAGE
166
167
    /* Making equivalent references in the destination file */
168
0
    for (i = 0; i < ref_count; i++) {
169
0
        const unsigned char *src_buf   = (const unsigned char *)&src_ref[i];
170
0
        unsigned char       *dst_buf   = (unsigned char *)&dst_ref[i];
171
0
        H5O_token_t          tmp_token = {0};
172
173
        /* If data is not initialized, copy zeros and skip */
174
0
        if (0 == memcmp(src_buf, zeros, buf_size))
175
0
            memset(dst_buf, 0, buf_size);
176
0
        else {
177
            /* Set up for the object copy for the reference */
178
0
            if (H5R__decode_token_obj_compat(src_buf, &buf_size, &tmp_token, token_size) < 0)
179
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode src object address");
180
0
            if (H5VL_native_token_to_addr(src_oloc->file, H5I_FILE, tmp_token, &src_oloc->addr) < 0)
181
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL,
182
0
                            "can't deserialize object token into address");
183
184
0
            if (!H5_addr_defined(src_oloc->addr) || src_oloc->addr == 0)
185
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "undefined reference pointer");
186
0
            dst_oloc->addr = HADDR_UNDEF;
187
188
            /* Attempt to copy object from source to destination file */
189
0
            if (H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0)
190
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object");
191
192
            /* Set the object reference info for the destination file */
193
0
            if (H5VL_native_addr_to_token(dst_oloc->file, H5I_FILE, dst_oloc->addr, &tmp_token) < 0)
194
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token");
195
0
            if (H5R__encode_token_obj_compat((const H5O_token_t *)&tmp_token, token_size, dst_buf,
196
0
                                             &buf_size) < 0)
197
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to encode dst object address");
198
0
        } /* end else */
199
0
    }     /* end for */
200
201
0
done:
202
0
    FUNC_LEAVE_NOAPI(ret_value)
203
0
} /* end H5O__copy_expand_ref_object1() */
204
205
/*-------------------------------------------------------------------------
206
 * Function:    H5O__copy_expand_ref_region1
207
 *
208
 * Purpose: Copy the object pointed by a deprecated region reference.
209
 *
210
 * Return:  Non-negative on success/Negative on failure
211
 *
212
 *-------------------------------------------------------------------------
213
 */
214
static herr_t
215
H5O__copy_expand_ref_region1(H5O_loc_t *src_oloc, const void *buf_src, H5O_loc_t *dst_oloc,
216
                             H5G_loc_t *dst_root_loc, void *buf_dst, size_t ref_count, H5O_copy_t *cpy_info)
217
0
{
218
0
    const hdset_reg_ref_t *src_ref                          = (const hdset_reg_ref_t *)buf_src;
219
0
    hdset_reg_ref_t       *dst_ref                          = (hdset_reg_ref_t *)buf_dst;
220
0
    const unsigned char    zeros[H5R_DSET_REG_REF_BUF_SIZE] = {0};
221
0
    size_t                 buf_size                         = H5R_DSET_REG_REF_BUF_SIZE;
222
0
    size_t                 i; /* Local index variable */
223
0
    herr_t                 ret_value = SUCCEED;
224
225
0
    FUNC_ENTER_PACKAGE
226
227
    /* Making equivalent references in the destination file */
228
0
    for (i = 0; i < ref_count; i++) {
229
0
        const unsigned char *src_buf = (const unsigned char *)&src_ref[i];
230
0
        unsigned char       *dst_buf = (unsigned char *)&dst_ref[i];
231
0
        unsigned char       *data    = NULL;
232
0
        size_t               data_size;
233
0
        const uint8_t       *p;
234
0
        uint8_t             *q;
235
236
        /* If data is not initialized, copy zeros and skip */
237
0
        if (0 == memcmp(src_buf, zeros, buf_size))
238
0
            memset(dst_buf, 0, buf_size);
239
0
        else {
240
            /* Read from heap */
241
0
            if (H5R__decode_heap(src_oloc->file, src_buf, &buf_size, &data, &data_size) < 0)
242
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode dataset region information");
243
244
            /* Get object address */
245
0
            p = (const uint8_t *)data;
246
0
            H5F_addr_decode(src_oloc->file, &p, &src_oloc->addr);
247
0
            if (!H5_addr_defined(src_oloc->addr) || src_oloc->addr == 0) {
248
0
                H5MM_free(data);
249
0
                HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "undefined reference pointer");
250
0
            }
251
0
            dst_oloc->addr = HADDR_UNDEF;
252
253
            /* Attempt to copy object from source to destination file */
254
0
            if (H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0) {
255
0
                H5MM_free(data);
256
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object");
257
0
            } /* end if */
258
259
            /* Serialize object addr */
260
0
            q = (uint8_t *)data;
261
0
            H5F_addr_encode(dst_oloc->file, &q, dst_oloc->addr);
262
263
            /* Write to heap */
264
0
            if (H5R__encode_heap(dst_oloc->file, dst_buf, &buf_size, data, (size_t)data_size) < 0) {
265
0
                H5MM_free(data);
266
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode dataset region information");
267
0
            }
268
269
            /* Free the buffer allocated in H5R__decode_heap() */
270
0
            H5MM_free(data);
271
0
        } /* end else */
272
0
    }     /* end for */
273
274
0
done:
275
0
    FUNC_LEAVE_NOAPI(ret_value)
276
0
} /* end H5O__copy_expand_ref_region1() */
277
278
/*-------------------------------------------------------------------------
279
 * Function:    H5O__copy_expand_ref_object2
280
 *
281
 * Purpose: Copy the object pointed by a reference (object, region, attribute).
282
 *
283
 * Return:  Non-negative on success/Negative on failure
284
 *
285
 *-------------------------------------------------------------------------
286
 */
287
static herr_t
288
H5O__copy_expand_ref_object2(H5O_loc_t *src_oloc, const H5T_t *dt_src, const void *buf_src, size_t nbytes_src,
289
                             H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, void *buf_dst, size_t ref_count,
290
                             H5O_copy_t *cpy_info)
291
0
{
292
0
    H5T_t              *dt_mem        = NULL;                        /* Memory datatype */
293
0
    H5T_t              *dt_dst        = NULL;                        /* Destination datatype */
294
0
    H5T_path_t         *tpath_src_mem = NULL, *tpath_mem_dst = NULL; /* Datatype conversion paths */
295
0
    size_t              i;                                           /* Local index variable */
296
0
    hid_t               dst_loc_id              = H5I_INVALID_HID;
297
0
    void               *conv_buf                = NULL;        /* Buffer for converting data */
298
0
    size_t              conv_buf_size           = 0;           /* Buffer size */
299
0
    void               *reclaim_buf             = NULL;        /* Buffer for reclaiming data */
300
0
    H5S_t              *buf_space               = NULL;        /* Dataspace describing buffer */
301
0
    hsize_t             buf_dim[1]              = {ref_count}; /* Dimension for buffer */
302
0
    size_t              token_size              = H5F_SIZEOF_ADDR(src_oloc->file);
303
0
    const unsigned char zeros[H5R_REF_BUF_SIZE] = {0};
304
0
    herr_t              ret_value               = SUCCEED;
305
306
0
    FUNC_ENTER_PACKAGE
307
308
    /* create a memory copy of the reference datatype */
309
0
    if (NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
310
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy");
311
312
    /* create reference datatype at the destination file */
313
0
    if (NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
314
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy");
315
0
    if (H5T_set_loc(dt_dst, H5F_VOL_OBJ(dst_oloc->file), H5T_LOC_DISK) < 0) {
316
0
        (void)H5T_close_real(dt_dst);
317
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "cannot mark datatype on disk");
318
0
    } /* end if */
319
320
    /* Set up the conversion functions */
321
0
    if (NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem)))
322
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes");
323
0
    if (NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst)))
324
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes");
325
326
    /* Use extra conversion buffer (TODO we should avoid using an extra buffer once the H5Ocopy code has been
327
     * reworked) */
328
0
    conv_buf_size = MAX(H5T_get_size(dt_src), H5T_get_size(dt_mem)) * ref_count;
329
0
    if (NULL == (conv_buf = H5FL_BLK_MALLOC(type_conv, conv_buf_size)))
330
0
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer");
331
0
    H5MM_memcpy(conv_buf, buf_src, nbytes_src);
332
333
    /* Convert from source file to memory */
334
0
    if (H5T_convert(tpath_src_mem, dt_src, dt_mem, ref_count, (size_t)0, (size_t)0, conv_buf, NULL) < 0)
335
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTCONVERT, FAIL, "datatype conversion failed");
336
337
    /* Retrieve loc ID */
338
0
    if ((dst_loc_id = H5F_get_id(dst_oloc->file)) < 0)
339
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object");
340
341
    /* Making equivalent references in the destination file */
342
0
    for (i = 0; i < ref_count; i++) {
343
0
        H5R_ref_t      *ref_ptr = (H5R_ref_t *)conv_buf;
344
0
        H5R_ref_priv_t *ref     = (H5R_ref_priv_t *)&ref_ptr[i];
345
346
        /* Check for null reference - only expand reference if it is not null */
347
0
        if (memcmp(ref, zeros, H5R_REF_BUF_SIZE)) {
348
0
            H5O_token_t tmp_token = {0};
349
350
            /* Get src object address */
351
0
            if (H5R__get_obj_token(ref, &tmp_token, &token_size) < 0)
352
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object token");
353
0
            if (H5VL_native_token_to_addr(src_oloc->file, H5I_FILE, tmp_token, &src_oloc->addr) < 0)
354
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTUNSERIALIZE, FAIL,
355
0
                            "can't deserialize object token into address");
356
357
            /* Attempt to copy object from source to destination file */
358
0
            if (H5O__copy_obj_by_ref(src_oloc, dst_oloc, dst_root_loc, cpy_info) < 0)
359
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object");
360
361
            /* Set dst object address */
362
0
            if (H5VL_native_addr_to_token(dst_oloc->file, H5I_FILE, dst_oloc->addr, &tmp_token) < 0)
363
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTSERIALIZE, FAIL, "can't serialize address into object token");
364
0
            if (H5R__set_obj_token(ref, (const H5O_token_t *)&tmp_token, token_size) < 0)
365
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set object token");
366
            /* Do not set app_ref since references are released once the copy is done */
367
0
            if (H5R__set_loc_id(ref, dst_loc_id, true, false) < 0)
368
0
                HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "unable to set destination loc id");
369
0
        } /* end if */
370
0
    }     /* end for */
371
372
    /* Copy into another buffer, to reclaim memory later */
373
0
    if (NULL == (reclaim_buf = H5FL_BLK_MALLOC(type_conv, conv_buf_size)))
374
0
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer");
375
0
    H5MM_memcpy(reclaim_buf, conv_buf, conv_buf_size);
376
0
    if (NULL == (buf_space = H5S_create_simple((unsigned)1, buf_dim, NULL)))
377
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create simple dataspace");
378
379
    /* Convert from memory to destination file */
380
0
    if (H5T_convert(tpath_mem_dst, dt_mem, dt_dst, ref_count, (size_t)0, (size_t)0, conv_buf, NULL) < 0)
381
0
        HGOTO_ERROR(H5E_OHDR, H5E_CANTCONVERT, FAIL, "datatype conversion failed");
382
0
    H5MM_memcpy(buf_dst, conv_buf, nbytes_src);
383
384
    /* Reclaim space from reference data */
385
0
    if (H5T_reclaim(dt_mem, buf_space, reclaim_buf) < 0)
386
0
        HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to reclaim reference data");
387
388
0
done:
389
0
    if (buf_space && (H5S_close(buf_space) < 0))
390
0
        HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "can't close dataspace");
391
0
    if (dt_mem && (H5T_close(dt_mem) < 0))
392
0
        HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype");
393
0
    if (dt_dst && (H5T_close(dt_dst) < 0))
394
0
        HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close temporary datatype");
395
0
    if (reclaim_buf)
396
0
        reclaim_buf = H5FL_BLK_FREE(type_conv, reclaim_buf);
397
0
    if (conv_buf)
398
0
        conv_buf = H5FL_BLK_FREE(type_conv, conv_buf);
399
0
    if ((dst_loc_id != H5I_INVALID_HID) && (H5I_dec_ref(dst_loc_id) < 0))
400
0
        HDONE_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement refcount on location id");
401
402
0
    FUNC_LEAVE_NOAPI(ret_value)
403
0
} /* end H5O__copy_expand_ref_object2() */
404
405
/*-------------------------------------------------------------------------
406
 * Function:  H5O_copy_expand_ref
407
 *
408
 * Purpose: Copy the object pointed by a reference.
409
 *
410
 * Return:  Non-negative on success/Negative on failure
411
 *
412
 *-------------------------------------------------------------------------
413
 */
414
herr_t
415
H5O_copy_expand_ref(H5F_t *file_src, const H5T_t *dt_src, void *buf_src, size_t nbytes_src, H5F_t *file_dst,
416
                    void *buf_dst, H5O_copy_t *cpy_info)
417
0
{
418
0
    H5O_loc_t dst_oloc;     /* Copied object object location */
419
0
    H5O_loc_t src_oloc;     /* Temporary object location for source object */
420
0
    H5G_loc_t dst_root_loc; /* The location of root group of the destination file */
421
0
    size_t    ref_count;
422
0
    herr_t    ret_value = SUCCEED;
423
424
0
    FUNC_ENTER_NOAPI(FAIL)
425
426
    /* Sanity checks */
427
0
    assert(file_src);
428
0
    assert(buf_src);
429
0
    assert(file_dst);
430
0
    assert(buf_dst);
431
0
    assert(nbytes_src);
432
0
    assert(cpy_info);
433
434
    /* Initialize object locations */
435
0
    H5O_loc_reset(&src_oloc);
436
0
    H5O_loc_reset(&dst_oloc);
437
0
    src_oloc.file = file_src;
438
0
    dst_oloc.file = file_dst;
439
440
    /* Set up the root group in the destination file */
441
0
    if (NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(file_dst))))
442
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group");
443
0
    if (NULL == (dst_root_loc.path = H5G_nameof(H5G_rootof(file_dst))))
444
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group");
445
446
    /* Determine # of reference elements to copy */
447
0
    ref_count = nbytes_src / H5T_get_size(dt_src);
448
449
    /* Copy object references */
450
0
    switch (H5T_get_ref_type(dt_src)) {
451
0
        case H5R_OBJECT1:
452
0
            if (H5O__copy_expand_ref_object1(&src_oloc, buf_src, &dst_oloc, &dst_root_loc, buf_dst, ref_count,
453
0
                                             cpy_info) < 0)
454
0
                HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to expand H5R_OBJECT1 reference");
455
0
            break;
456
0
        case H5R_DATASET_REGION1:
457
0
            if (H5O__copy_expand_ref_region1(&src_oloc, buf_src, &dst_oloc, &dst_root_loc, buf_dst, ref_count,
458
0
                                             cpy_info) < 0)
459
0
                HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to expand H5R_DATASET_REGION1 reference");
460
0
            break;
461
0
        case H5R_DATASET_REGION2:
462
0
        case H5R_ATTR:
463
0
        case H5R_OBJECT2:
464
0
            if (H5O__copy_expand_ref_object2(&src_oloc, dt_src, buf_src, nbytes_src, &dst_oloc, &dst_root_loc,
465
0
                                             buf_dst, ref_count, cpy_info) < 0)
466
0
                HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to expand reference");
467
0
            break;
468
0
        case H5R_BADTYPE:
469
0
        case H5R_MAXTYPE:
470
0
        default:
471
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type");
472
0
            break;
473
0
    } /* end switch */
474
475
0
done:
476
0
    FUNC_LEAVE_NOAPI(ret_value)
477
0
} /* end H5O_copy_expand_ref() */