1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 #define H5A_PACKAGE /*prevent warning from including H5Apkg */
15 #define H5O_PACKAGE /*suppress error about including H5Opkg */
16 #define H5S_PACKAGE /*suppress error about including H5Spkg */
17
18
19 #include "H5private.h" /* Generic Functions */
20 #include "H5Apkg.h" /* Attributes */
21 #include "H5Eprivate.h" /* Error handling */
22 #include "H5MMprivate.h" /* Memory management */
23 #include "H5Opkg.h" /* Object headers */
24 #include "H5Spkg.h" /* Dataspaces */
25
26 /* PRIVATE PROTOTYPES */
27 static herr_t H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg);
28 static void *H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
29 unsigned mesg_flags, unsigned *ioflags, size_t p_size, const uint8_t *p);
30 static void *H5O_attr_copy(const void *_mesg, void *_dest);
31 static size_t H5O_attr_size(const H5F_t *f, const void *_mesg);
32 static herr_t H5O_attr_free(void *mesg);
33 static herr_t H5O_attr_pre_copy_file(H5F_t *file_src, const void *mesg_src,
34 hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata);
35 static void *H5O_attr_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
36 void *native_src, H5F_t *file_dst, hbool_t *recompute_size,
37 H5O_copy_t *cpy_info, void *udata, hid_t dxpl_id);
38 static herr_t H5O_attr_post_copy_file(const H5O_loc_t *src_oloc,
39 const void *mesg_src, H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id,
40 H5O_copy_t *cpy_info);
41 static herr_t H5O_attr_get_crt_index(const void *_mesg, H5O_msg_crt_idx_t *crt_idx);
42 static herr_t H5O_attr_set_crt_index(void *_mesg, H5O_msg_crt_idx_t crt_idx);
43 static herr_t H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
44 FILE * stream, int indent, int fwidth);
45
46 /* Set up & include shared message "interface" info */
47 #define H5O_SHARED_TYPE H5O_MSG_ATTR
48 #define H5O_SHARED_DECODE H5O_attr_shared_decode
49 #define H5O_SHARED_DECODE_REAL H5O_attr_decode
50 #define H5O_SHARED_ENCODE H5O_attr_shared_encode
51 #define H5O_SHARED_ENCODE_REAL H5O_attr_encode
52 #define H5O_SHARED_SIZE H5O_attr_shared_size
53 #define H5O_SHARED_SIZE_REAL H5O_attr_size
54 #define H5O_SHARED_DELETE H5O_attr_shared_delete
55 #define H5O_SHARED_DELETE_REAL H5O_attr_delete
56 #define H5O_SHARED_LINK H5O_attr_shared_link
57 #define H5O_SHARED_LINK_REAL H5O_attr_link
58 #define H5O_SHARED_COPY_FILE H5O_attr_shared_copy_file
59 #define H5O_SHARED_COPY_FILE_REAL H5O_attr_copy_file
60 #define H5O_SHARED_POST_COPY_FILE H5O_attr_shared_post_copy_file
61 #define H5O_SHARED_POST_COPY_FILE_REAL H5O_attr_post_copy_file
62 #undef H5O_SHARED_POST_COPY_FILE_UPD
63 #define H5O_SHARED_DEBUG H5O_attr_shared_debug
64 #define H5O_SHARED_DEBUG_REAL H5O_attr_debug
65 #include "H5Oshared.h" /* Shared Object Header Message Callbacks */
66
67 /* This message derives from H5O message class */
68 const H5O_msg_class_t H5O_MSG_ATTR[1] = {{
69 H5O_ATTR_ID, /* message id number */
70 "attribute", /* message name for debugging */
71 sizeof(H5A_t), /* native message size */
72 H5O_SHARE_IS_SHARABLE, /* messages are sharable? */
73 H5O_attr_shared_decode, /* decode message */
74 H5O_attr_shared_encode, /* encode message */
75 H5O_attr_copy, /* copy the native value */
76 H5O_attr_shared_size, /* size of raw message */
77 H5O_attr_reset, /* reset method */
78 H5O_attr_free, /* free method */
79 H5O_attr_shared_delete, /* file delete method */
80 H5O_attr_shared_link, /* link method */
81 NULL, /*set share method */
82 NULL, /*can share method */
83 H5O_attr_pre_copy_file, /* pre copy native value to file */
84 H5O_attr_shared_copy_file, /* copy native value to file */
85 H5O_attr_shared_post_copy_file, /* post copy native value to file */
86 H5O_attr_get_crt_index, /* get creation index */
87 H5O_attr_set_crt_index, /* set creation index */
88 H5O_attr_shared_debug /* debug the message */
89 }};
90
91 /* Flags for attribute flag encoding */
92 #define H5O_ATTR_FLAG_TYPE_SHARED 0x01
93 #define H5O_ATTR_FLAG_SPACE_SHARED 0x02
94 #define H5O_ATTR_FLAG_ALL 0x03
95
96 /* Declare external the free list for H5S_t's */
97 H5FL_EXTERN(H5S_t);
98
99 /* Declare external the free list for H5S_extent_t's */
100 H5FL_EXTERN(H5S_extent_t);
101
102
103 /*--------------------------------------------------------------------------
104 NAME
105 H5O_attr_decode
106 PURPOSE
107 Decode a attribute message and return a pointer to a memory struct
108 with the decoded information
109 USAGE
110 void *H5O_attr_decode(f, dxpl_id, mesg_flags, p)
111 H5F_t *f; IN: pointer to the HDF5 file struct
112 hid_t dxpl_id; IN: DXPL for any I/O
113 unsigned mesg_flags; IN: Message flags to influence decoding
114 const uint8_t *p; IN: the raw information buffer
115 RETURNS
116 Pointer to the new message in native order on success, NULL on failure
117 DESCRIPTION
118 This function decodes the "raw" disk form of a attribute message
119 into a struct in memory native format. The struct is allocated within this
120 function using malloc() and is returned to the caller.
121 --------------------------------------------------------------------------*/
122 static void *
H5O_attr_decode(H5F_t * f,hid_t dxpl_id,H5O_t * open_oh,unsigned H5_ATTR_UNUSED mesg_flags,unsigned * ioflags,size_t H5_ATTR_UNUSED p_size,const uint8_t * p)123 H5O_attr_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned H5_ATTR_UNUSED mesg_flags,
124 unsigned *ioflags, size_t H5_ATTR_UNUSED p_size, const uint8_t *p)
125 {
126 H5A_t *attr = NULL;
127 H5S_extent_t *extent; /*extent dimensionality information */
128 size_t name_len; /*attribute name length */
129 unsigned flags = 0; /* Attribute flags */
130 H5A_t *ret_value; /* Return value */
131
132 FUNC_ENTER_NOAPI_NOINIT
133
134 /* check args */
135 HDassert(f);
136 HDassert(p);
137
138 if(NULL == (attr = H5FL_CALLOC(H5A_t)))
139 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
140
141 if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t)))
142 HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared attr structure")
143
144 /* Version number */
145 attr->shared->version = *p++;
146 if(attr->shared->version < H5O_ATTR_VERSION_1 || attr->shared->version > H5O_ATTR_VERSION_LATEST)
147 HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, NULL, "bad version number for attribute message")
148
149 /* Get the flags byte if we have a later version of the attribute */
150 if(attr->shared->version >= H5O_ATTR_VERSION_2) {
151 flags = *p++;
152
153 /* Check for unknown flag */
154 if(flags & (unsigned)~H5O_ATTR_FLAG_ALL)
155 HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, NULL, "unknown flag for attribute message")
156 } /* end if */
157 else
158 p++; /* Byte is unused when version<2 */
159
160 /*
161 * Decode the sizes of the parts of the attribute. The sizes stored in
162 * the file are exact but the parts are aligned on 8-byte boundaries.
163 */
164 UINT16DECODE(p, name_len); /*including null*/
165 UINT16DECODE(p, attr->shared->dt_size);
166 UINT16DECODE(p, attr->shared->ds_size);
167
168 /*
169 * Decode the character encoding for the name for versions 3 or later,
170 * as well as some reserved bytes.
171 */
172 if(attr->shared->version >= H5O_ATTR_VERSION_3)
173 attr->shared->encoding = (H5T_cset_t)*p++;
174
175 /* Decode and store the name */
176 if(NULL == (attr->shared->name = H5MM_strdup((const char *)p)))
177 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
178 if(attr->shared->version < H5O_ATTR_VERSION_2)
179 p += H5O_ALIGN_OLD(name_len); /* advance the memory pointer */
180 else
181 p += name_len; /* advance the memory pointer */
182
183 /* Decode the attribute's datatype */
184 if(NULL == (attr->shared->dt = (H5T_t *)(H5O_MSG_DTYPE->decode)(f, dxpl_id, open_oh,
185 ((flags & H5O_ATTR_FLAG_TYPE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), ioflags, attr->shared->dt_size, p)))
186 HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype")
187 if(attr->shared->version < H5O_ATTR_VERSION_2)
188 p += H5O_ALIGN_OLD(attr->shared->dt_size);
189 else
190 p += attr->shared->dt_size;
191
192 /* decode the attribute dataspace. It can be shared in versions >= 3
193 * What's actually shared, though, is only the extent.
194 */
195 if(NULL == (attr->shared->ds = H5FL_CALLOC(H5S_t)))
196 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
197
198 /* Decode attribute's dataspace extent */
199 if((extent = (H5S_extent_t *)(H5O_MSG_SDSPACE->decode)(f, dxpl_id, open_oh,
200 ((flags & H5O_ATTR_FLAG_SPACE_SHARED) ? H5O_MSG_FLAG_SHARED : 0), ioflags, attr->shared->ds_size, p)) == NULL)
201 HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace")
202
203 /* Copy the extent information to the dataspace */
204 HDmemcpy(&(attr->shared->ds->extent), extent, sizeof(H5S_extent_t));
205
206 /* Release temporary extent information */
207 extent = H5FL_FREE(H5S_extent_t, extent);
208
209 /* Default to entire dataspace being selected */
210 if(H5S_select_all(attr->shared->ds, FALSE) < 0)
211 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection")
212
213 if(attr->shared->version < H5O_ATTR_VERSION_2)
214 p += H5O_ALIGN_OLD(attr->shared->ds_size);
215 else
216 p += attr->shared->ds_size;
217
218 /* Compute the size of the data */
219 H5_CHECKED_ASSIGN(attr->shared->data_size, size_t, H5S_GET_EXTENT_NPOINTS(attr->shared->ds) * H5T_get_size(attr->shared->dt), hsize_t);
220
221 /* Go get the data */
222 if(attr->shared->data_size) {
223 if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, attr->shared->data_size)))
224 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
225 HDmemcpy(attr->shared->data, p, attr->shared->data_size);
226 } /* end if */
227
228 /* Increment the reference count for this object header message in cache(compact
229 storage) or for the object from dense storage. */
230 attr->shared->nrefs++;
231
232 /* Set return value */
233 ret_value = attr;
234
235 done:
236 if(NULL == ret_value)
237 if(attr) {
238 if(attr->shared) {
239 /* Free any dynamicly allocated items */
240 if(H5A_free(attr) < 0)
241 HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't release attribute info")
242
243 /* Destroy shared attribute struct */
244 attr->shared = H5FL_FREE(H5A_shared_t, attr->shared);
245 } /* end if */
246
247 attr = H5FL_FREE(H5A_t, attr);
248 } /* end if */
249
250 FUNC_LEAVE_NOAPI(ret_value)
251 } /* end H5O_attr_decode() */
252
253
254 /*--------------------------------------------------------------------------
255 NAME
256 H5O_attr_encode
257 PURPOSE
258 Encode a simple attribute message
259 USAGE
260 herr_t H5O_attr_encode(f, p, mesg)
261 H5F_t *f; IN: pointer to the HDF5 file struct
262 const uint8 *p; IN: the raw information buffer
263 const void *mesg; IN: Pointer to the simple datatype struct
264 RETURNS
265 Non-negative on success/Negative on failure
266 DESCRIPTION
267 This function encodes the native memory form of the attribute
268 message in the "raw" disk form.
269 --------------------------------------------------------------------------*/
270 static herr_t
H5O_attr_encode(H5F_t * f,uint8_t * p,const void * mesg)271 H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg)
272 {
273 const H5A_t *attr = (const H5A_t *) mesg;
274 size_t name_len; /* Attribute name length */
275 htri_t is_type_shared; /* Flag to indicate that a shared datatype is used for this attribute */
276 htri_t is_space_shared; /* Flag to indicate that a shared dataspace is used for this attribute */
277 unsigned flags = 0; /* Attribute flags */
278 herr_t ret_value = SUCCEED; /* Return value */
279
280 FUNC_ENTER_NOAPI_NOINIT
281
282 /* check args */
283 HDassert(f);
284 HDassert(p);
285 HDassert(attr);
286
287 /* Check whether datatype and dataspace are shared */
288 if((is_type_shared = H5O_msg_is_shared(H5O_DTYPE_ID, attr->shared->dt)) < 0)
289 HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't determine if datatype is shared")
290
291 if((is_space_shared = H5O_msg_is_shared(H5O_SDSPACE_ID, attr->shared->ds)) < 0)
292 HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't determine if dataspace is shared")
293
294 /* Encode Version */
295 *p++ = attr->shared->version;
296
297 /* Set attribute flags if version >1 */
298 if(attr->shared->version >= H5O_ATTR_VERSION_2) {
299 flags = (is_type_shared ? H5O_ATTR_FLAG_TYPE_SHARED : 0 );
300 flags |= (is_space_shared ? H5O_ATTR_FLAG_SPACE_SHARED : 0);
301 *p++ = (uint8_t)flags; /* Set flags for attribute */
302 } /* end if */
303 else
304 *p++ = 0; /* Reserved, for version <2 */
305
306 /*
307 * Encode the lengths of the various parts of the attribute message. The
308 * encoded lengths are exact but we pad each part except the data to be a
309 * multiple of eight bytes (in the first version).
310 */
311 name_len = HDstrlen(attr->shared->name) + 1;
312 UINT16ENCODE(p, name_len);
313 UINT16ENCODE(p, attr->shared->dt_size);
314 UINT16ENCODE(p, attr->shared->ds_size);
315
316 /* The character encoding for the attribute's name, in later versions */
317 if(attr->shared->version >= H5O_ATTR_VERSION_3)
318 *p++ = attr->shared->encoding;
319
320 /* Write the name including null terminator */
321 HDmemcpy(p, attr->shared->name, name_len);
322 if(attr->shared->version < H5O_ATTR_VERSION_2) {
323 /* Pad to the correct number of bytes */
324 HDmemset(p + name_len, 0, H5O_ALIGN_OLD(name_len) - name_len);
325 p += H5O_ALIGN_OLD(name_len);
326 } /* end if */
327 else
328 p += name_len;
329
330 /* encode the attribute datatype */
331 if((H5O_MSG_DTYPE->encode)(f, FALSE, p, attr->shared->dt) < 0)
332 HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype")
333
334 if(attr->shared->version < H5O_ATTR_VERSION_2) {
335 HDmemset(p + attr->shared->dt_size, 0, H5O_ALIGN_OLD(attr->shared->dt_size) - attr->shared->dt_size);
336 p += H5O_ALIGN_OLD(attr->shared->dt_size);
337 } /* end if */
338 else
339 p += attr->shared->dt_size;
340
341 /* encode the attribute dataspace */
342 if((H5O_MSG_SDSPACE->encode)(f, FALSE, p, &(attr->shared->ds->extent)) < 0)
343 HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute dataspace")
344
345 if(attr->shared->version < H5O_ATTR_VERSION_2) {
346 HDmemset(p + attr->shared->ds_size, 0, H5O_ALIGN_OLD(attr->shared->ds_size) - attr->shared->ds_size);
347 p += H5O_ALIGN_OLD(attr->shared->ds_size);
348 } /* end if */
349 else
350 p += attr->shared->ds_size;
351
352 /* Store attribute data. If there's no data, store 0 as fill value. */
353 if(attr->shared->data)
354 HDmemcpy(p, attr->shared->data, attr->shared->data_size);
355 else
356 HDmemset(p, 0, attr->shared->data_size);
357
358 done:
359 FUNC_LEAVE_NOAPI(ret_value);
360 } /* end H5O_attr_encode() */
361
362
363 /*--------------------------------------------------------------------------
364 NAME
365 H5O_attr_copy
366 PURPOSE
367 Copies a message from MESG to DEST, allocating DEST if necessary.
368 USAGE
369 void *H5O_attr_copy(mesg, dest)
370 const void *mesg; IN: Pointer to the source attribute struct
371 const void *dest; IN: Pointer to the destination attribute struct
372 RETURNS
373 Pointer to DEST on success, NULL on failure
374 DESCRIPTION
375 This function copies a native (memory) attribute message,
376 allocating the destination structure if necessary.
377 --------------------------------------------------------------------------*/
378 static void *
H5O_attr_copy(const void * _src,void * _dst)379 H5O_attr_copy(const void *_src, void *_dst)
380 {
381 void *ret_value; /* Return value */
382
383 FUNC_ENTER_NOAPI_NOINIT
384
385 /* check args */
386 HDassert(_src);
387
388 /* copy */
389 if(NULL == (ret_value = (H5A_t *)H5A_copy((H5A_t *)_dst, (const H5A_t *)_src)))
390 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "can't copy attribute")
391
392 done:
393 FUNC_LEAVE_NOAPI(ret_value)
394 } /* end H5O_attr_copy() */
395
396
397 /*--------------------------------------------------------------------------
398 NAME
399 H5O_attr_size
400 PURPOSE
401 Return the raw message size in bytes
402 USAGE
403 size_t H5O_attr_size(f, mesg)
404 H5F_t *f; IN: pointer to the HDF5 file struct
405 const void *mesg; IN: Pointer to the source attribute struct
406 RETURNS
407 Size of message on success, 0 on failure
408 DESCRIPTION
409 This function returns the size of the raw attribute message on
410 success. (Not counting the message type or size fields, only the data
411 portion of the message). It doesn't take into account alignment.
412 --------------------------------------------------------------------------*/
413 static size_t
H5O_attr_size(const H5F_t H5_ATTR_UNUSED * f,const void * _mesg)414 H5O_attr_size(const H5F_t H5_ATTR_UNUSED *f, const void *_mesg)
415 {
416 const H5A_t *attr = (const H5A_t *)_mesg;
417 size_t name_len;
418 size_t ret_value = 0;
419
420 FUNC_ENTER_NOAPI_NOINIT_NOERR
421
422 HDassert(attr);
423
424 /* Common size information */
425 ret_value = 1 + /*version */
426 1 + /*reserved/flags */
427 2 + /*name size inc. null */
428 2 + /*type size */
429 2; /*space size */
430
431 /* Length of attribute name */
432 name_len = HDstrlen(attr->shared->name) + 1;
433
434 /* Version-specific size information */
435 if(attr->shared->version == H5O_ATTR_VERSION_1)
436 ret_value += H5O_ALIGN_OLD(name_len) + /*attribute name */
437 H5O_ALIGN_OLD(attr->shared->dt_size) + /*datatype */
438 H5O_ALIGN_OLD(attr->shared->ds_size) + /*dataspace */
439 attr->shared->data_size; /*the data itself */
440 else if(attr->shared->version == H5O_ATTR_VERSION_2)
441 ret_value += name_len + /*attribute name */
442 attr->shared->dt_size + /*datatype */
443 attr->shared->ds_size + /*dataspace */
444 attr->shared->data_size; /*the data itself */
445 else if(attr->shared->version == H5O_ATTR_VERSION_3)
446 ret_value += 1 + /*character encoding */
447 name_len + /*attribute name */
448 attr->shared->dt_size + /*datatype */
449 attr->shared->ds_size + /*dataspace */
450 attr->shared->data_size; /*the data itself */
451 else
452 HDassert(0 && "Bad attribute version");
453
454 FUNC_LEAVE_NOAPI(ret_value)
455 } /* end H5O_attr_size() */
456
457
458 /*-------------------------------------------------------------------------
459 * Function: H5O_attr_reset
460 *
461 * Purpose: Frees resources within a attribute message, but doesn't free
462 * the message itself.
463 *
464 * Return: Non-negative on success/Negative on failure
465 *
466 * Programmer: Robb Matzke
467 * Tuesday, December 9, 1997
468 *
469 * Modification:Raymond Lu
470 * 25 June 2008
471 * Made this function empty. The freeing action is actually
472 * done in H5O_attr_free (see H5O_msg_free_real). But this
473 * empty reset function needs to be here. Otherwise, the
474 * caller function H5O_msg_reset_real will zero-set the whole
475 * message.
476 *-------------------------------------------------------------------------
477 */
478 herr_t
H5O_attr_reset(void H5_ATTR_UNUSED * _mesg)479 H5O_attr_reset(void H5_ATTR_UNUSED *_mesg)
480 {
481 FUNC_ENTER_NOAPI_NOINIT_NOERR
482
483 FUNC_LEAVE_NOAPI(SUCCEED)
484 } /* end H5O_attr_reset() */
485
486
487 /*-------------------------------------------------------------------------
488 * Function: H5O_attr_free
489 *
490 * Purpose: Free's the message
491 *
492 * Return: Non-negative on success/Negative on failure
493 *
494 * Programmer: Quincey Koziol
495 * Thursday, November 18, 2004
496 *
497 * Modification:Raymond Lu
498 * 4 June 2008
499 * Let this function call H5A_close in turn.
500 *
501 *-------------------------------------------------------------------------
502 */
503 static herr_t
H5O_attr_free(void * mesg)504 H5O_attr_free(void *mesg)
505 {
506 H5A_t *attr = (H5A_t *)mesg;
507 herr_t ret_value = SUCCEED; /* Return value */
508
509 FUNC_ENTER_NOAPI_NOINIT
510
511 HDassert(mesg);
512
513 if(H5A_close(attr) < 0)
514 HGOTO_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, FAIL, "unable to close attribute object")
515
516 done:
517 FUNC_LEAVE_NOAPI(ret_value)
518 } /* end H5O_attr_free() */
519
520
521 /*-------------------------------------------------------------------------
522 * Function: H5O_attr_delete
523 *
524 * Purpose: Free file space referenced by message
525 *
526 * Return: Non-negative on success/Negative on failure
527 *
528 * Programmer: Quincey Koziol
529 * Friday, September 26, 2003
530 *
531 *-------------------------------------------------------------------------
532 */
533 herr_t
H5O_attr_delete(H5F_t * f,hid_t dxpl_id,H5O_t * oh,void * _mesg)534 H5O_attr_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, void *_mesg)
535 {
536 H5A_t *attr = (H5A_t *) _mesg;
537 herr_t ret_value = SUCCEED; /* Return value */
538
539 FUNC_ENTER_NOAPI_NOINIT
540
541 /* check args */
542 HDassert(f);
543 HDassert(attr);
544
545 /* Decrement reference count on datatype in file */
546 if((H5O_MSG_DTYPE->del)(f, dxpl_id, oh, attr->shared->dt) < 0)
547 HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust datatype link count")
548
549 /* Decrement reference count on dataspace in file */
550 if((H5O_MSG_SDSPACE->del)(f, dxpl_id, oh, attr->shared->ds) < 0)
551 HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust dataspace link count")
552
553 done:
554 FUNC_LEAVE_NOAPI(ret_value)
555 } /* end H5O_attr_delete() */
556
557
558 /*-------------------------------------------------------------------------
559 * Function: H5O_attr_link
560 *
561 * Purpose: Increment reference count on any objects referenced by
562 * message
563 *
564 * Return: Non-negative on success/Negative on failure
565 *
566 * Programmer: Quincey Koziol
567 * Friday, September 26, 2003
568 *
569 *-------------------------------------------------------------------------
570 */
571 herr_t
H5O_attr_link(H5F_t * f,hid_t dxpl_id,H5O_t * oh,void * _mesg)572 H5O_attr_link(H5F_t *f, hid_t dxpl_id, H5O_t *oh, void *_mesg)
573 {
574 H5A_t *attr = (H5A_t *) _mesg;
575 herr_t ret_value = SUCCEED; /* Return value */
576
577 FUNC_ENTER_NOAPI_NOINIT
578
579 /* check args */
580 HDassert(f);
581 HDassert(attr);
582
583 /* Re-share attribute's datatype and dataspace to increment their
584 * reference count if they're shared.
585 * Otherwise they may be deleted when the attribute
586 * message is deleted.
587 */
588 /* Increment reference count on datatype & dataspace in file */
589 if((H5O_MSG_DTYPE->link)(f, dxpl_id, oh, attr->shared->dt) < 0)
590 HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust datatype link count")
591 if((H5O_MSG_SDSPACE->link)(f, dxpl_id, oh, attr->shared->ds) < 0)
592 HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust dataspace link count")
593
594 done:
595 FUNC_LEAVE_NOAPI(ret_value)
596 } /* end H5O_attr_link() */
597
598
599 /*-------------------------------------------------------------------------
600 * Function: H5O_attr_pre_copy_file
601 *
602 * Purpose: Perform any necessary actions before copying message between
603 * files for attribute messages.
604 *
605 * Return: Success: Non-negative
606 *
607 * Failure: Negative
608 *
609 * Programmer: Quincey Koziol
610 * Monday, June 26, 2006
611 *
612 *-------------------------------------------------------------------------
613 */
614 static herr_t
H5O_attr_pre_copy_file(H5F_t H5_ATTR_UNUSED * file_src,const void H5_ATTR_UNUSED * native_src,hbool_t * deleted,const H5O_copy_t * cpy_info,void H5_ATTR_UNUSED * udata)615 H5O_attr_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void H5_ATTR_UNUSED *native_src,
616 hbool_t *deleted, const H5O_copy_t *cpy_info, void H5_ATTR_UNUSED *udata)
617 {
618 FUNC_ENTER_NOAPI_NOINIT_NOERR
619
620 /* check args */
621 HDassert(deleted);
622 HDassert(cpy_info);
623
624 /* If we are not copying attributes into the destination file, indicate
625 * that this message should be deleted.
626 */
627 if(cpy_info->copy_without_attr)
628 *deleted = TRUE;
629
630 FUNC_LEAVE_NOAPI(SUCCEED)
631 } /* end H5O_attr_pre_copy_file() */
632
633
634 /*-------------------------------------------------------------------------
635 * Function: H5O_attr_copy_file
636 *
637 * Purpose: Copies a message from _MESG to _DEST in file
638 *
639 * Return: Success: Ptr to _DEST
640 *
641 * Failure: NULL
642 *
643 * Programmer: Quincey Koziol
644 * November 1, 2005
645 *
646 *-------------------------------------------------------------------------
647 */
648 static void *
H5O_attr_copy_file(H5F_t * file_src,const H5O_msg_class_t H5_ATTR_UNUSED * mesg_type,void * native_src,H5F_t * file_dst,hbool_t * recompute_size,H5O_copy_t * cpy_info,void H5_ATTR_UNUSED * udata,hid_t dxpl_id)649 H5O_attr_copy_file(H5F_t *file_src, const H5O_msg_class_t H5_ATTR_UNUSED *mesg_type,
650 void *native_src, H5F_t *file_dst, hbool_t *recompute_size,
651 H5O_copy_t *cpy_info, void H5_ATTR_UNUSED *udata, hid_t dxpl_id)
652 {
653 void *ret_value; /* Return value */
654
655 FUNC_ENTER_NOAPI_NOINIT
656
657 /* check args */
658 HDassert(native_src);
659 HDassert(file_dst);
660 HDassert(cpy_info);
661 HDassert(!cpy_info->copy_without_attr);
662
663 /* Mark datatype as being on disk now. This step used to be done in a lower level
664 * by H5O_dtype_decode. But it has been moved up. Not an ideal place, but no better
665 * place than here. */
666 if(H5T_set_loc(((H5A_t *)native_src)->shared->dt, file_src, H5T_LOC_DISK) < 0)
667 HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "invalid datatype location")
668
669 if(NULL == (ret_value = H5A_attr_copy_file((H5A_t *)native_src, file_dst, recompute_size, cpy_info, dxpl_id)))
670 HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy attribute")
671
672 done:
673 FUNC_LEAVE_NOAPI(ret_value)
674 } /* H5O_attr_copy_file() */
675
676
677 /*-------------------------------------------------------------------------
678 * Function: H5O_attr_post_copy_file
679 *
680 * Purpose: Finish copying a message from between files.
681 * We have to copy the values of a reference attribute in the
682 * post copy because H5O_post_copy_file() fails at the case that
683 * an object may have a reference attribute that points to the
684 * object itself.
685 *
686 * Return: Non-negative on success/Negative on failure
687 *
688 * Programmer: Peter Cao
689 * March 6, 2005
690 *
691 *-------------------------------------------------------------------------
692 */
693 static herr_t
H5O_attr_post_copy_file(const H5O_loc_t * src_oloc,const void * mesg_src,H5O_loc_t * dst_oloc,void * mesg_dst,hid_t dxpl_id,H5O_copy_t * cpy_info)694 H5O_attr_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
695 H5O_loc_t *dst_oloc, void *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
696 {
697 herr_t ret_value = SUCCEED; /* Return value */
698
699
700 FUNC_ENTER_NOAPI_NOINIT
701
702 if ( H5A_attr_post_copy_file(src_oloc, (const H5A_t *)mesg_src,
703 dst_oloc, (H5A_t *)mesg_dst, dxpl_id, cpy_info) < 0)
704 HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "can't copy attribute")
705
706 done:
707 FUNC_LEAVE_NOAPI(ret_value)
708 } /* H5O_attr_post_copy_file() */
709
710
711 /*-------------------------------------------------------------------------
712 * Function: H5O_attr_get_crt_index
713 *
714 * Purpose: Get creation index from the message
715 *
716 * Return: Success: Non-negative
717 * Failure: Negative
718 *
719 * Programmer: Quincey Koziol
720 * Thursday, January 18, 2007
721 *
722 *-------------------------------------------------------------------------
723 */
724 static herr_t
H5O_attr_get_crt_index(const void * _mesg,H5O_msg_crt_idx_t * crt_idx)725 H5O_attr_get_crt_index(const void *_mesg, H5O_msg_crt_idx_t *crt_idx /*out*/)
726 {
727 const H5A_t *attr = (const H5A_t *)_mesg;
728
729 FUNC_ENTER_NOAPI_NOINIT_NOERR
730
731 HDassert(attr);
732 HDassert(crt_idx);
733
734 /* Get the attribute's creation index */
735 *crt_idx = attr->shared->crt_idx;
736
737 FUNC_LEAVE_NOAPI(SUCCEED)
738 } /* end H5O_attr_get_crt_index() */
739
740
741 /*-------------------------------------------------------------------------
742 * Function: H5O_attr_set_crt_index
743 *
744 * Purpose: Set creation index from the message
745 *
746 * Return: Success: Non-negative
747 * Failure: Negative
748 *
749 * Programmer: Quincey Koziol
750 * Thursday, January 18, 2007
751 *
752 *-------------------------------------------------------------------------
753 */
754 static herr_t
H5O_attr_set_crt_index(void * _mesg,H5O_msg_crt_idx_t crt_idx)755 H5O_attr_set_crt_index(void *_mesg, H5O_msg_crt_idx_t crt_idx)
756 {
757 H5A_t *attr = (H5A_t *)_mesg;
758
759 FUNC_ENTER_NOAPI_NOINIT_NOERR
760
761 HDassert(attr);
762
763 /* Set the creation index */
764 attr->shared->crt_idx = crt_idx;
765
766 FUNC_LEAVE_NOAPI(SUCCEED)
767 } /* end H5O_attr_set_crt_index() */
768
769
770 /*--------------------------------------------------------------------------
771 NAME
772 H5O_attr_debug
773 PURPOSE
774 Prints debugging information for an attribute message
775 USAGE
776 void *H5O_attr_debug(f, mesg, stream, indent, fwidth)
777 H5F_t *f; IN: pointer to the HDF5 file struct
778 const void *mesg; IN: Pointer to the source attribute struct
779 FILE *stream; IN: Pointer to the stream for output data
780 int indent; IN: Amount to indent information by
781 int fwidth; IN: Field width (?)
782 RETURNS
783 Non-negative on success/Negative on failure
784 DESCRIPTION
785 This function prints debugging output to the stream passed as a
786 parameter.
787 --------------------------------------------------------------------------*/
788 static herr_t
H5O_attr_debug(H5F_t * f,hid_t dxpl_id,const void * _mesg,FILE * stream,int indent,int fwidth)789 H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int indent,
790 int fwidth)
791 {
792 const H5A_t *mesg = (const H5A_t *)_mesg;
793 const char *s; /* Temporary string pointer */
794 char buf[128]; /* Temporary string buffer */
795 herr_t ret_value = SUCCEED; /* Return value */
796
797 FUNC_ENTER_NOAPI_NOINIT
798
799 /* check args */
800 HDassert(f);
801 HDassert(stream);
802 HDassert(indent >= 0);
803 HDassert(fwidth >= 0);
804
805 HDfprintf(stream, "%*s%-*s \"%s\"\n", indent, "", fwidth,
806 "Name:",
807 mesg->shared->name);
808 switch(mesg->shared->encoding) {
809 case H5T_CSET_ASCII:
810 s = "ASCII";
811 break;
812
813 case H5T_CSET_UTF8:
814 s = "UTF-8";
815 break;
816
817 case H5T_CSET_RESERVED_2:
818 case H5T_CSET_RESERVED_3:
819 case H5T_CSET_RESERVED_4:
820 case H5T_CSET_RESERVED_5:
821 case H5T_CSET_RESERVED_6:
822 case H5T_CSET_RESERVED_7:
823 case H5T_CSET_RESERVED_8:
824 case H5T_CSET_RESERVED_9:
825 case H5T_CSET_RESERVED_10:
826 case H5T_CSET_RESERVED_11:
827 case H5T_CSET_RESERVED_12:
828 case H5T_CSET_RESERVED_13:
829 case H5T_CSET_RESERVED_14:
830 case H5T_CSET_RESERVED_15:
831 HDsnprintf(buf, sizeof(buf), "H5T_CSET_RESERVED_%d", (int)(mesg->shared->encoding));
832 s = buf;
833 break;
834
835 case H5T_CSET_ERROR:
836 default:
837 HDsnprintf(buf, sizeof(buf), "Unknown character set: %d", (int)(mesg->shared->encoding));
838 s = buf;
839 break;
840 } /* end switch */
841 HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
842 "Character Set of Name:",
843 s);
844 HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth,
845 "Object opened:",
846 mesg->obj_opened);
847 HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
848 "Object:",
849 mesg->oloc.addr);
850
851 /* Check for attribute creation order index on the attribute */
852 if(mesg->shared->crt_idx != H5O_MAX_CRT_ORDER_IDX)
853 HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
854 "Creation Index:",
855 (unsigned)mesg->shared->crt_idx);
856
857 HDfprintf(stream, "%*sDatatype...\n", indent, "");
858 HDfprintf(stream, "%*s%-*s %lu\n", indent + 3, "", MAX(0,fwidth - 3),
859 "Encoded Size:",
860 (unsigned long)(mesg->shared->dt_size));
861 if((H5O_MSG_DTYPE->debug)(f, dxpl_id, mesg->shared->dt, stream, indent + 3, MAX(0, fwidth - 3)) < 0)
862 HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to display datatype message info")
863
864 HDfprintf(stream, "%*sDataspace...\n", indent, "");
865 HDfprintf(stream, "%*s%-*s %lu\n", indent + 3, "", MAX(0, fwidth - 3),
866 "Encoded Size:",
867 (unsigned long)(mesg->shared->ds_size));
868 if(H5S_debug(f, dxpl_id, mesg->shared->ds, stream, indent + 3, MAX(0, fwidth - 3)) < 0)
869 HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to display dataspace message info")
870
871 done:
872 FUNC_LEAVE_NOAPI(ret_value)
873 } /* end H5O_attr_debug() */
874
875