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://www.hdfgroup.org/licenses.               *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 #if !(defined H5O_FRIEND || defined H5O_MODULE)
15 #error "Do not include this file outside the H5O package!"
16 #endif
17 
18 #ifndef H5Opkg_H
19 #define H5Opkg_H
20 
21 /* Get package's private header */
22 #include "H5Oprivate.h" /* Object headers		  	*/
23 
24 /* Other private headers needed by this file */
25 #include "H5ACprivate.h" /* Metadata cache                       */
26 #include "H5FLprivate.h" /* Free Lists                           */
27 
28 /* Object header macros */
29 #define H5O_NMESGS  8 /*initial number of messages	     */
30 #define H5O_NCHUNKS 2 /*initial number of chunks	     */
31 #define H5O_MIN_SIZE                                                                                         \
32     22 /* Min. obj header data size (must be big enough for a message prefix and a continuation message) */
33 #define H5O_MSG_TYPES         26    /* # of types of messages            */
34 #define H5O_MAX_CRT_ORDER_IDX 65535 /* Max. creation order index value   */
35 
36 /* Versions of object header structure */
37 
38 /* Initial version of the object header format */
39 #define H5O_VERSION_1 1
40 
41 /* Revised version - leaves out reserved bytes and alignment padding, and adds
42  *      magic number as prefix and checksum as suffix for all chunks.
43  */
44 #define H5O_VERSION_2 2
45 
46 /* The latest version of the format.  Look through the 'flush'
47  *      and 'size' callback for places to change when updating this. */
48 #define H5O_VERSION_LATEST H5O_VERSION_2
49 
50 /*
51  * Align messages on 8-byte boundaries because we would like to copy the
52  * object header chunks directly into memory and operate on them there, even
53  * on 64-bit architectures.  This allows us to reduce the number of disk I/O
54  * requests with a minimum amount of mem-to-mem copies.
55  *
56  * Note: We no longer attempt to do this. - QAK, 10/16/06
57  */
58 #define H5O_ALIGN_OLD(X)     (8 * (((X) + 7) / 8))
59 #define H5O_ALIGN_VERS(V, X) (((V) == H5O_VERSION_1) ? H5O_ALIGN_OLD(X) : (X))
60 #define H5O_ALIGN_OH(O, X)   H5O_ALIGN_VERS((O)->version, X)
61 #define H5O_ALIGN_F(F, X)    H5O_ALIGN_VERS(MAX(H5O_VERSION_1, (uint8_t)H5O_obj_ver_bounds[H5F_LOW_BOUND(F)]), X)
62 
63 /* Size of checksum (on disk) */
64 #define H5O_SIZEOF_CHKSUM 4
65 
66 /* ========= Object Creation properties ============ */
67 /* Default values for some of the object creation properties */
68 /* NOTE: The H5O_CRT_ATTR_MAX_COMPACT_DEF & H5O_CRT_ATTR_MIN_DENSE_DEF values
69  *      are "built into" the file format, make certain existing files with
70  *      default attribute phase change storage are handled correctly if they
71  *      are changed.
72  */
73 #define H5O_CRT_ATTR_MAX_COMPACT_DEF 8
74 #define H5O_CRT_ATTR_MIN_DENSE_DEF   6
75 #define H5O_CRT_OHDR_FLAGS_DEF       H5O_HDR_STORE_TIMES
76 
77 /* Object header status flag definitions */
78 #define H5O_HDR_CHUNK0_1 0x00 /* Use 1-byte value for chunk #0 size */
79 #define H5O_HDR_CHUNK0_2 0x01 /* Use 2-byte value for chunk #0 size */
80 #define H5O_HDR_CHUNK0_4 0x02 /* Use 4-byte value for chunk #0 size */
81 #define H5O_HDR_CHUNK0_8 0x03 /* Use 8-byte value for chunk #0 size */
82 
83 /*
84  * Size of object header prefix.
85  */
86 #define H5O_SIZEOF_HDR(O)                                                                                    \
87     (((O)->version == H5O_VERSION_1)                                                                         \
88          ? H5O_ALIGN_OLD(1 +                           /*version number	*/                                   \
89                          1 +                           /*reserved 		*/                                       \
90                          2 +                           /*number of messages	*/                               \
91                          4 +                           /*reference count	*/                                  \
92                          4)                            /*chunk data size	*/                                  \
93          : (H5_SIZEOF_MAGIC +                          /*magic number  	*/                                   \
94             1 +                                        /*version number 	*/                                  \
95             1 +                                        /*flags		 	*/                                         \
96             (((O)->flags & H5O_HDR_STORE_TIMES) ? (4 + /*access time		*/                                     \
97                                                    4 + /*modification time	*/                                \
98                                                    4 + /*change time		*/                                     \
99                                                    4   /*birth time		*/                                      \
100                                                    )                                                         \
101                                                 : 0) +                                                       \
102             (((O)->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) ? (2 + /*max compact attributes */               \
103                                                                2   /*min dense attributes	*/                 \
104                                                                )                                             \
105                                                             : 0) +                                           \
106             (1 << ((O)->flags & H5O_HDR_CHUNK0_SIZE)) + /*chunk 0 data size */                               \
107             H5O_SIZEOF_CHKSUM)                          /*checksum size	*/                                   \
108     )
109 
110 /*
111  * Size of object header message prefix
112  */
113 #define H5O_SIZEOF_MSGHDR_VERS(V, C)                                                                         \
114     (((V) == H5O_VERSION_1) ? H5O_ALIGN_OLD(2u + /*message type		*/                                           \
115                                             2 + /*sizeof message data	*/                                     \
116                                             1 + /*flags              	*/                                     \
117                                             3)  /*reserved		*/                                               \
118                             : (1 +              /*message type		*/                                           \
119                                2 +              /*sizeof message data	*/                                     \
120                                1 +              /*flags              	*/                                     \
121                                ((C) ? (2        /*creation index     	*/                                     \
122                                        )                                                                     \
123                                     : 0)))
124 #define H5O_SIZEOF_MSGHDR_OH(O)                                                                              \
125     (unsigned)H5O_SIZEOF_MSGHDR_VERS((O)->version, (O)->flags &H5O_HDR_ATTR_CRT_ORDER_TRACKED)
126 #define H5O_SIZEOF_MSGHDR_F(F, C)                                                                            \
127     (unsigned)H5O_SIZEOF_MSGHDR_VERS(MAX((H5F_STORE_MSG_CRT_IDX(F) ? H5O_VERSION_LATEST : H5O_VERSION_1),    \
128                                          (uint8_t)H5O_obj_ver_bounds[H5F_LOW_BOUND(F)]),                     \
129                                      (C))
130 
131 /*
132  * Size of chunk "header" for each chunk
133  */
134 #define H5O_SIZEOF_CHKHDR_VERS(V)                                                                            \
135     (((V) == H5O_VERSION_1) ? 0 +                   /*no magic #  */                                         \
136                                   0                 /*no checksum */                                         \
137                             : H5_SIZEOF_MAGIC +     /*magic #  */                                            \
138                                   H5O_SIZEOF_CHKSUM /*checksum */                                            \
139     )
140 #define H5O_SIZEOF_CHKHDR_OH(O) H5O_SIZEOF_CHKHDR_VERS((O)->version)
141 
142 /*
143  * Size of checksum for each chunk
144  */
145 #define H5O_SIZEOF_CHKSUM_VERS(V)                                                                            \
146     (((V) == H5O_VERSION_1) ? 0                 /*no checksum */                                             \
147                             : H5O_SIZEOF_CHKSUM /*checksum */                                                \
148     )
149 #define H5O_SIZEOF_CHKSUM_OH(O) H5O_SIZEOF_CHKSUM_VERS((O)->version)
150 
151 /* Input/output flags for decode functions */
152 #define H5O_DECODEIO_NOCHANGE 0x01u /* IN: do not modify values */
153 #define H5O_DECODEIO_DIRTY    0x02u /* OUT: message has been changed */
154 
155 /* Macro to incremend ndecode_dirtied (only if we are debugging) */
156 #ifndef NDEBUG
157 #define INCR_NDECODE_DIRTIED(OH) (OH)->ndecode_dirtied++;
158 #else /* NDEBUG */
159 #define INCR_NDECODE_DIRTIED(OH) ;
160 #endif /* NDEBUG */
161 
162 /* Load native information for a message, if it's not already present */
163 /* (Only works for messages with decode callback) */
164 #define H5O_LOAD_NATIVE(F, IOF, OH, MSG, ERR)                                                                \
165     if (NULL == (MSG)->native) {                                                                             \
166         const H5O_msg_class_t *msg_type = (MSG)->type;                                                       \
167         unsigned               ioflags  = (IOF);                                                             \
168                                                                                                              \
169         /* Decode the message */                                                                             \
170         HDassert(msg_type->decode);                                                                          \
171         if (NULL == ((MSG)->native = (msg_type->decode)((F), (OH), (MSG)->flags, &ioflags, (MSG)->raw_size,  \
172                                                         (MSG)->raw)))                                        \
173             HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, ERR, "unable to decode message")                           \
174                                                                                                              \
175         /* Mark the message dirty if it was changed by decoding */                                           \
176         if ((ioflags & H5O_DECODEIO_DIRTY) && (H5F_get_intent((F)) & H5F_ACC_RDWR)) {                        \
177             (MSG)->dirty = TRUE;                                                                             \
178             /* Increment the count of messages dirtied by decoding, but */                                   \
179             /* only ifndef NDEBUG */                                                                         \
180             INCR_NDECODE_DIRTIED(OH)                                                                         \
181         }                                                                                                    \
182                                                                                                              \
183         /* Set the message's "shared info", if it's shareable */                                             \
184         if ((MSG)->flags & H5O_MSG_FLAG_SHAREABLE) {                                                         \
185             HDassert(msg_type->share_flags &H5O_SHARE_IS_SHARABLE);                                          \
186             H5O_UPDATE_SHARED((H5O_shared_t *)(MSG)->native, H5O_SHARE_TYPE_HERE, (F), msg_type->id,         \
187                               (MSG)->crt_idx, (OH)->chunk[0].addr)                                           \
188         } /* end if */                                                                                       \
189                                                                                                              \
190         /* Set the message's "creation index", if it has one */                                              \
191         if (msg_type->set_crt_index) {                                                                       \
192             /* Set the creation index for the message */                                                     \
193             if ((msg_type->set_crt_index)((MSG)->native, (MSG)->crt_idx) < 0)                                \
194                 HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, ERR, "unable to set creation index")                      \
195         } /* end if */                                                                                       \
196     }     /* end if */
197 
198 /* Flags for a message class's "sharability" */
199 #define H5O_SHARE_IS_SHARABLE 0x01
200 #define H5O_SHARE_IN_OHDR     0x02
201 
202 /* Set the object header size to speculatively read in */
203 /* (needs to be more than the object header prefix size to work at all and
204  *      should be larger than the largest object type's default object header
205  *      size to save the extra I/O operations) */
206 #define H5O_SPEC_READ_SIZE 512
207 
208 /* The "message class" type */
209 struct H5O_msg_class_t {
210     unsigned    id;          /*message type ID on disk   */
211     const char *name;        /*for debugging             */
212     size_t      native_size; /*size of native message    */
213     unsigned    share_flags; /* Message sharing settings */
214     void *(*decode)(H5F_t *, H5O_t *, unsigned, unsigned *, size_t, const uint8_t *);
215     herr_t (*encode)(H5F_t *, hbool_t, uint8_t *, const void *);
216     void *(*copy)(const void *, void *);                      /*copy native value         */
217     size_t (*raw_size)(const H5F_t *, hbool_t, const void *); /*sizeof encoded message	*/
218     herr_t (*reset)(void *);                                  /*free nested data structs  */
219     herr_t (*free)(void *);                                   /*free main data struct  */
220     herr_t (*del)(H5F_t *, H5O_t *, void *);  /* Delete space in file referenced by this message */
221     herr_t (*link)(H5F_t *, H5O_t *, void *); /* Increment any links in file reference by this message */
222     herr_t (*set_share)(void *, const H5O_shared_t *); /* Set shared information */
223     htri_t (*can_share)(const void *);                 /* Is message allowed to be shared? */
224     herr_t (*pre_copy_file)(H5F_t *, const void *, hbool_t *, const H5O_copy_t *,
225                             void *); /*"pre copy" action when copying native value to file */
226     void *(*copy_file)(H5F_t *, void *, H5F_t *, hbool_t *, unsigned *, H5O_copy_t *,
227                        void *); /*copy native value to file */
228     herr_t (*post_copy_file)(const H5O_loc_t *, const void *, H5O_loc_t *, void *, unsigned *,
229                              H5O_copy_t *); /*"post copy" action when copying native value to file */
230     herr_t (*get_crt_index)(const void *, H5O_msg_crt_idx_t *); /* Get message's creation index */
231     herr_t (*set_crt_index)(void *, H5O_msg_crt_idx_t);         /* Set message's creation index */
232     herr_t (*debug)(H5F_t *, const void *, FILE *, int, int);
233 };
234 
235 struct H5O_mesg_t {
236     const H5O_msg_class_t *type;     /* type of message                  */
237     hbool_t                dirty;    /* raw out of date wrt native       */
238     uint8_t                flags;    /* message flags                    */
239     H5O_msg_crt_idx_t      crt_idx;  /* message creation index           */
240     unsigned               chunkno;  /* chunk number for this mesg       */
241     void *                 native;   /* native format message            */
242     uint8_t *              raw;      /* pointer to raw data              */
243     size_t                 raw_size; /* size with alignment              */
244 };
245 
246 /* Struct for storing information about "best" message to move to new chunk */
247 typedef struct H5O_msg_alloc_info_t {
248     int      msgno;      /* Index in message array */
249     unsigned id;         /* Message type ID on disk */
250     unsigned chunkno;    /* Index in chunk array */
251     size_t   gap_size;   /* Size of any "gap" in the chunk immediately after message */
252     size_t   null_size;  /* Size of any null message in the chunk immediately after message */
253     size_t   total_size; /* Total size of "available" space around message */
254     unsigned null_msgno; /* Message index of null message immediately after message */
255 } H5O_msg_alloc_info_t;
256 
257 typedef struct H5O_chunk_t {
258     haddr_t                   addr;        /*chunk file address		     */
259     size_t                    size;        /*chunk size			     */
260     size_t                    gap;         /*space at end of chunk too small for null message */
261     uint8_t *                 image;       /*image of file			     */
262     struct H5O_chunk_proxy_t *chunk_proxy; /* Pointer to a chunk's proxy when chunk protected */
263 } H5O_chunk_t;
264 
265 struct H5O_t {
266     H5AC_info_t cache_info; /* Information for metadata cache functions, _must_ be */
267                             /* first field in structure */
268 
269     /* File-specific information (not stored) */
270     size_t  sizeof_size; /* Size of file sizes 		     */
271     size_t  sizeof_addr; /* Size of file addresses	     */
272     hbool_t swmr_write;  /* Whether we are doing SWMR writes  */
273 
274     /* Debugging information (not stored) */
275 #ifdef H5O_ENABLE_BAD_MESG_COUNT
276     hbool_t store_bad_mesg_count; /* Flag to indicate that a bad message count should be stored */
277                                   /* (This is to simulate a bug in earlier
278                                    *      versions of the library)
279                                    */
280 #endif                            /* H5O_ENABLE_BAD_MESG_COUNT */
281 #ifndef NDEBUG
282     size_t ndecode_dirtied; /* Number of messages dirtied by decoding */
283 #endif                      /* NDEBUG */
284 
285     /* Chunk management information (not stored) */
286     size_t rc; /* Reference count of [continuation] chunks using this structure */
287 
288     /* Object information (stored) */
289     hbool_t  has_refcount_msg; /* Whether the object has a ref. count message */
290     unsigned nlink;            /*link count			     */
291     uint8_t  version;          /*version number		     */
292     uint8_t  flags;            /*flags				     */
293 
294     /* Time information (stored, for versions > 1 & H5O_HDR_STORE_TIMES flag set) */
295     time_t atime; /*access time 			     */
296     time_t mtime; /*modification time 		     */
297     time_t ctime; /*change time 			     */
298     time_t btime; /*birth time 			     */
299 
300     /* Attribute information (stored, for versions > 1) */
301     unsigned max_compact; /* Maximum # of compact attributes   */
302     unsigned min_dense;   /* Minimum # of "dense" attributes   */
303 
304     /* Message management (stored, encoded in chunks) */
305     size_t      nmesgs;         /*number of messages		     */
306     size_t      alloc_nmesgs;   /*number of message slots	     */
307     H5O_mesg_t *mesg;           /*array of messages		     */
308     size_t      link_msgs_seen; /* # of link messages seen when loading header */
309     size_t      attr_msgs_seen; /* # of attribute messages seen when loading header */
310 
311     /* Chunk management (not stored) */
312     size_t       nchunks;       /*number of chunks		     */
313     size_t       alloc_nchunks; /*chunks allocated		     */
314     H5O_chunk_t *chunk;         /*array of chunks		     */
315     hbool_t      chunks_pinned; /* Whether chunks are pinned from ohdr protect */
316 
317     /* Object header proxy information (not stored) */
318     H5AC_proxy_entry_t *proxy; /* Proxy cache entry for all ohdr entries */
319 };
320 
321 /* Class for types of objects in file */
322 typedef struct H5O_obj_class_t {
323     H5O_type_t  type;                               /*object type on disk	     */
324     const char *name;                               /*for debugging		     */
325     void *(*get_copy_file_udata)(void);             /*retrieve user data for 'copy file' operation */
326     void (*free_copy_file_udata)(void *);           /*free user data for 'copy file' operation */
327     htri_t (*isa)(const H5O_t *);                   /*if a header matches an object class */
328     void *(*open)(const H5G_loc_t *, H5I_type_t *); /*open an object of this class */
329     void *(*create)(H5F_t *, void *, H5G_loc_t *);  /*create an object of this class */
330     H5O_loc_t *(*get_oloc)(hid_t);                  /*get the object header location for an object */
331     herr_t (*bh_info)(const H5O_loc_t *loc, H5O_t *oh,
332                       H5_ih_info_t *bh_info); /*get the index & heap info for an object */
333     herr_t (*flush)(void *obj_ptr);           /*flush an opened object of this class */
334 } H5O_obj_class_t;
335 
336 /* Node in skip list to map addresses from one file to another during object header copy */
337 typedef struct H5O_addr_map_t {
338     H5_obj_t               src_obj_pos;   /* Location of source object */
339     haddr_t                dst_addr;      /* Address of object in destination file */
340     hbool_t                is_locked;     /* Indicate that the destination object is locked currently */
341     hsize_t                inc_ref_count; /* Number of deferred increments to reference count */
342     const H5O_obj_class_t *obj_class;     /* Object class */
343     void *                 udata;         /* Object class copy file udata */
344 } H5O_addr_map_t;
345 
346 /* Stack of continuation messages to interpret */
347 typedef struct H5O_cont_msgs_t {
348     size_t      nmsgs;       /* Number of continuation messages found so far */
349     size_t      alloc_nmsgs; /* Continuation messages allocated */
350     H5O_cont_t *msgs;        /* Array of continuation messages */
351 } H5O_cont_msgs_t;
352 
353 /* Common callback information for loading object header prefix from disk */
354 typedef struct H5O_common_cache_ud_t {
355     H5F_t *          f;                /* Pointer to file for object header/chunk */
356     unsigned         file_intent;      /* Read/write intent for file */
357     unsigned         merged_null_msgs; /* Number of null messages merged together */
358     H5O_cont_msgs_t *cont_msg_info;    /* Pointer to continuation messages to work on */
359     haddr_t          addr;             /* Address of the prefix or chunk */
360 } H5O_common_cache_ud_t;
361 
362 /* Callback information for loading object header prefix from disk */
363 typedef struct H5O_cache_ud_t {
364     hbool_t               made_attempt;  /* Whether the deserialize routine was already attempted */
365     unsigned              v1_pfx_nmesgs; /* Number of messages from v1 prefix header */
366     size_t                chunk0_size;   /* Size of serialized first chunk    */
367     H5O_t *               oh;            /* Partially deserialized object header, for later use */
368     hbool_t               free_oh;       /* Whether to free the object header or not */
369     H5O_common_cache_ud_t common;        /* Common object header cache callback info */
370 } H5O_cache_ud_t;
371 
372 /* Structure representing each chunk in the cache */
373 typedef struct H5O_chunk_proxy_t {
374     H5AC_info_t cache_info; /* Information for metadata cache functions, _must_ be */
375                             /* first field in structure */
376 
377     H5F_t *  f;       /* Pointer to file for object header/chunk */
378     H5O_t *  oh;      /* Object header for this chunk */
379     unsigned chunkno; /* Chunk number for this chunk */
380 
381     /* Flush depencency parent information (not stored)
382      *
383      * The following field is used to store a pointer
384      * to the in-core representation of a new chunk proxy's flush dependency
385      * parent -- if it exists.  If it does not exist, this field will
386      * contain NULL.
387      *
388      * If the file is opened in SWMR write mode, the flush dependency
389      * parent of the chunk proxy will be either its object header
390      * or the chunk with the continuation message that references this chunk.
391      */
392     void *fd_parent; /* Pointer to flush dependency parent */
393 } H5O_chunk_proxy_t;
394 
395 /* Callback information for loading object header chunk from disk */
396 typedef struct H5O_chk_cache_ud_t {
397     hbool_t               decoding; /* Whether the object header is being decoded */
398     H5O_t *               oh;       /* Object header for this chunk */
399     unsigned              chunkno;  /* Index of chunk being brought in (for re-loads) */
400     size_t                size;     /* Size of chunk in the file */
401     H5O_common_cache_ud_t common;   /* Common object header cache callback info */
402 } H5O_chk_cache_ud_t;
403 
404 /* Header message ID to class mapping */
405 H5_DLLVAR const H5O_msg_class_t *const H5O_msg_class_g[H5O_MSG_TYPES];
406 
407 /* Declare external the free list for H5O_t's */
408 H5FL_EXTERN(H5O_t);
409 
410 /* Declare external the free list for H5O_mesg_t sequences */
411 H5FL_SEQ_EXTERN(H5O_mesg_t);
412 
413 /* Declare external the free list for H5O_chunk_t sequences */
414 H5FL_SEQ_EXTERN(H5O_chunk_t);
415 
416 /* Declare external the free list for chunk_image blocks */
417 H5FL_BLK_EXTERN(chunk_image);
418 
419 /*
420  * Object header messages
421  */
422 
423 /* Null Message. (0x0000) */
424 H5_DLLVAR const H5O_msg_class_t H5O_MSG_NULL[1];
425 
426 /* Simple Dataspace Message. (0x0001) */
427 H5_DLLVAR const H5O_msg_class_t H5O_MSG_SDSPACE[1];
428 
429 /* Link Information Message. (0x0002) */
430 H5_DLLVAR const H5O_msg_class_t H5O_MSG_LINFO[1];
431 
432 /* Datatype Message. (0x0003) */
433 H5_DLLVAR const H5O_msg_class_t H5O_MSG_DTYPE[1];
434 
435 /* Old Fill Value Message. (0x0004) */
436 H5_DLLVAR const H5O_msg_class_t H5O_MSG_FILL[1];
437 
438 /* New Fill Value Message. (0x0005) */
439 /*
440  * The new fill value message is fill value plus
441  * space allocation time and fill value writing time and whether fill
442  * value is defined.
443  */
444 H5_DLLVAR const H5O_msg_class_t H5O_MSG_FILL_NEW[1];
445 
446 /* Link Message. (0x0006) */
447 H5_DLLVAR const H5O_msg_class_t H5O_MSG_LINK[1];
448 
449 /* External File List Message. (0x0007) */
450 H5_DLLVAR const H5O_msg_class_t H5O_MSG_EFL[1];
451 
452 /* Data Layout Message. (0x0008) */
453 H5_DLLVAR const H5O_msg_class_t H5O_MSG_LAYOUT[1];
454 
455 #ifdef H5O_ENABLE_BOGUS
456 /* "Bogus valid" Message. (0x0009) */
457 /* "Bogus invalid" Message. (0x0019) */
458 /*
459  * Used for debugging - should never be found in valid HDF5 file.
460  */
461 H5_DLLVAR const H5O_msg_class_t H5O_MSG_BOGUS_VALID[1];
462 H5_DLLVAR const H5O_msg_class_t H5O_MSG_BOGUS_INVALID[1];
463 #endif /* H5O_ENABLE_BOGUS */
464 
465 /* Group Information Message. (0x000a) */
466 H5_DLLVAR const H5O_msg_class_t H5O_MSG_GINFO[1];
467 
468 /* Filter pipeline message. (0x000b) */
469 H5_DLLVAR const H5O_msg_class_t H5O_MSG_PLINE[1];
470 
471 /* Attribute Message. (0x000c) */
472 H5_DLLVAR const H5O_msg_class_t H5O_MSG_ATTR[1];
473 
474 /* Object name message. (0x000d) */
475 H5_DLLVAR const H5O_msg_class_t H5O_MSG_NAME[1];
476 
477 /* Modification Time Message. (0x000e) */
478 /*
479  * The message is just a `time_t'.
480  * (See also the "new" modification time message)
481  */
482 H5_DLLVAR const H5O_msg_class_t H5O_MSG_MTIME[1];
483 
484 /* Shared Message information message (0x000f)
485  * A message for the superblock extension, holding information about
486  * the file-wide shared message "SOHM" table
487  */
488 H5_DLLVAR const H5O_msg_class_t H5O_MSG_SHMESG[1];
489 
490 /* Object Header Continuation Message. (0x0010) */
491 H5_DLLVAR const H5O_msg_class_t H5O_MSG_CONT[1];
492 
493 /* Symbol Table Message. (0x0011) */
494 H5_DLLVAR const H5O_msg_class_t H5O_MSG_STAB[1];
495 
496 /* New Modification Time Message. (0x0012) */
497 /*
498  * The message is just a `time_t'.
499  */
500 H5_DLLVAR const H5O_msg_class_t H5O_MSG_MTIME_NEW[1];
501 
502 /* v1 B-tree 'K' value message (0x0013)
503  * A message for the superblock extension, holding information about
504  * the file-wide v1 B-tree 'K' values.
505  */
506 H5_DLLVAR const H5O_msg_class_t H5O_MSG_BTREEK[1];
507 
508 /* Driver info message (0x0014)
509  * A message for the superblock extension, holding information about
510  * the file driver settings
511  */
512 H5_DLLVAR const H5O_msg_class_t H5O_MSG_DRVINFO[1];
513 
514 /* Attribute Information Message. (0x0015) */
515 H5_DLLVAR const H5O_msg_class_t H5O_MSG_AINFO[1];
516 
517 /* Reference Count Message. (0x0016) */
518 H5_DLLVAR const H5O_msg_class_t H5O_MSG_REFCOUNT[1];
519 
520 /* Free-space Manager Info message. (0x0017) */
521 H5_DLLVAR const H5O_msg_class_t H5O_MSG_FSINFO[1];
522 
523 /* Metadata Cache Image message. (0x0018) */
524 H5_DLLVAR const H5O_msg_class_t H5O_MSG_MDCI[1];
525 
526 /* Placeholder for unknown message. (0x0019) */
527 H5_DLLVAR const H5O_msg_class_t H5O_MSG_UNKNOWN[1];
528 
529 /*
530  * Object header "object" types
531  */
532 
533 /* Group Object. (H5O_TYPE_GROUP - 0) */
534 H5_DLLVAR const H5O_obj_class_t H5O_OBJ_GROUP[1];
535 
536 /* Dataset Object. (H5O_TYPE_DATASET - 1) */
537 H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATASET[1];
538 
539 /* Datatype Object. (H5O_TYPE_NAMED_DATATYPE - 2) */
540 H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATATYPE[1];
541 
542 /* Package-local function prototypes */
543 H5_DLL void *H5O__open_by_addr(const H5G_loc_t *loc, haddr_t addr, H5I_type_t *opened_type /*out*/);
544 H5_DLL void *H5O__open_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type,
545                               H5_iter_order_t order, hsize_t n, H5I_type_t *opened_type /*out*/);
546 H5_DLL const H5O_obj_class_t *H5O__obj_class(const H5O_loc_t *loc);
547 H5_DLL herr_t                 H5O__copy(const H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc,
548                                         const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id);
549 H5_DLL int                    H5O__link_oh(H5F_t *f, int adjust, H5O_t *oh, hbool_t *deleted);
550 H5_DLL herr_t H5O__visit(H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order,
551                          H5O_iterate2_t op, void *op_data, unsigned fields);
552 H5_DLL herr_t H5O__inc_rc(H5O_t *oh);
553 H5_DLL herr_t H5O__dec_rc(H5O_t *oh);
554 H5_DLL herr_t H5O__free(H5O_t *oh);
555 
556 /* Object header message routines */
557 H5_DLL herr_t   H5O__msg_alloc(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, unsigned *mesg_flags,
558                                void *mesg, size_t *mesg_idx);
559 H5_DLL herr_t   H5O__msg_append_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, unsigned mesg_flags,
560                                      unsigned update_flags, void *mesg);
561 H5_DLL herr_t   H5O__msg_write_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, unsigned mesg_flags,
562                                     unsigned update_flags, void *mesg);
563 H5_DLL herr_t   H5O__msg_free_mesg(H5O_mesg_t *mesg);
564 H5_DLL unsigned H5O__msg_count_real(const H5O_t *oh, const H5O_msg_class_t *type);
565 H5_DLL herr_t   H5O__msg_remove_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, int sequence,
566                                      H5O_operator_t op, void *op_data, hbool_t adj_link);
567 H5_DLL void *H5O__msg_copy_file(const H5O_msg_class_t *type, H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
568                                 hbool_t *recompute_size, unsigned *mesg_flags, H5O_copy_t *cpy_info,
569                                 void *udata);
570 H5_DLL herr_t H5O__msg_iterate_real(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type,
571                                     const H5O_mesg_operator_t *op, void *op_data);
572 H5_DLL herr_t H5O__flush_msgs(H5F_t *f, H5O_t *oh);
573 H5_DLL herr_t H5O__delete_mesg(H5F_t *f, H5O_t *open_oh, H5O_mesg_t *mesg);
574 
575 /* Object header chunk routines */
576 H5_DLL herr_t H5O__chunk_add(H5F_t *f, H5O_t *oh, unsigned idx, unsigned cont_chunkno);
577 H5_DLL H5O_chunk_proxy_t *H5O__chunk_protect(H5F_t *f, H5O_t *oh, unsigned idx);
578 H5_DLL herr_t             H5O__chunk_unprotect(H5F_t *f, H5O_chunk_proxy_t *chk_proxy, hbool_t chk_dirtied);
579 H5_DLL herr_t             H5O__chunk_update_idx(H5F_t *f, H5O_t *oh, unsigned idx);
580 H5_DLL herr_t             H5O__chunk_resize(H5O_t *oh, H5O_chunk_proxy_t *chk_proxy);
581 H5_DLL herr_t             H5O__chunk_delete(H5F_t *f, H5O_t *oh, unsigned idx);
582 H5_DLL herr_t             H5O__chunk_dest(H5O_chunk_proxy_t *chunk_proxy);
583 
584 /* Collect storage info for btree and heap */
585 H5_DLL herr_t H5O__attr_bh_info(H5F_t *f, H5O_t *oh, H5_ih_info_t *bh_info);
586 
587 /* Object header allocation routines */
588 H5_DLL herr_t H5O__alloc_msgs(H5O_t *oh, size_t min_alloc);
589 H5_DLL herr_t H5O__alloc_chunk(H5F_t *f, H5O_t *oh, size_t size, size_t found_null,
590                                const H5O_msg_alloc_info_t *found_msg, size_t *new_idx);
591 H5_DLL herr_t H5O__alloc(H5F_t *f, H5O_t *oh, const H5O_msg_class_t *type, const void *mesg,
592                          size_t *mesg_idx);
593 H5_DLL herr_t H5O__condense_header(H5F_t *f, H5O_t *oh);
594 H5_DLL herr_t H5O__release_mesg(H5F_t *f, H5O_t *oh, H5O_mesg_t *mesg, hbool_t adj_link);
595 
596 /* Shared object operators */
597 H5_DLL void * H5O__shared_decode(H5F_t *f, H5O_t *open_oh, unsigned *ioflags, const uint8_t *buf,
598                                  const H5O_msg_class_t *type);
599 H5_DLL herr_t H5O__shared_encode(const H5F_t *f, uint8_t *buf /*out*/, const H5O_shared_t *sh_mesg);
600 H5_DLL size_t H5O__shared_size(const H5F_t *f, const H5O_shared_t *sh_mesg);
601 H5_DLL herr_t H5O__shared_delete(H5F_t *f, H5O_t *open_oh, const H5O_msg_class_t *mesg_type,
602                                  H5O_shared_t *sh_mesg);
603 H5_DLL herr_t H5O__shared_link(H5F_t *f, H5O_t *open_oh, const H5O_msg_class_t *mesg_type,
604                                H5O_shared_t *sh_mesg);
605 H5_DLL herr_t H5O__shared_copy_file(H5F_t *file_src, H5F_t *file_dst, const H5O_msg_class_t *mesg_type,
606                                     const void *_native_src, void *_native_dst, hbool_t *recompute_size,
607                                     unsigned *mesg_flags, H5O_copy_t *cpy_info, void *udata);
608 H5_DLL herr_t H5O__shared_post_copy_file(H5F_t *f, const H5O_msg_class_t *mesg_type,
609                                          const H5O_shared_t *shared_src, H5O_shared_t *shared_dst,
610                                          unsigned *mesg_flags, H5O_copy_t *cpy_info);
611 H5_DLL herr_t H5O__shared_debug(const H5O_shared_t *mesg, FILE *stream, int indent, int fwidth);
612 
613 /* Attribute message operators */
614 H5_DLL herr_t H5O__attr_reset(void *_mesg);
615 H5_DLL herr_t H5O__attr_delete(H5F_t *f, H5O_t *open_oh, void *_mesg);
616 H5_DLL herr_t H5O__attr_link(H5F_t *f, H5O_t *open_oh, void *_mesg);
617 H5_DLL herr_t H5O__attr_count_real(H5F_t *f, H5O_t *oh, hsize_t *nattrs);
618 
619 /* Arrays of versions for:
620  * Object header, Attribute/Fill value/Filter pipeline messages
621  */
622 /* Layout/Datatype/Dataspace arrays of versions are in H5Dpkg.h, H5Tpkg.h and H5Spkg.h */
623 H5_DLLVAR const unsigned H5O_obj_ver_bounds[H5F_LIBVER_NBOUNDS];
624 H5_DLLVAR const unsigned H5O_attr_ver_bounds[H5F_LIBVER_NBOUNDS];
625 H5_DLLVAR const unsigned H5O_fill_ver_bounds[H5F_LIBVER_NBOUNDS];
626 H5_DLLVAR const unsigned H5O_pline_ver_bounds[H5F_LIBVER_NBOUNDS];
627 
628 /* Testing functions */
629 #ifdef H5O_TESTING
630 H5_DLL htri_t H5O__is_attr_empty_test(hid_t oid);
631 H5_DLL htri_t H5O__is_attr_dense_test(hid_t oid);
632 H5_DLL herr_t H5O__num_attrs_test(hid_t oid, hsize_t *nattrs);
633 H5_DLL herr_t H5O__attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count);
634 H5_DLL herr_t H5O__check_msg_marked_test(hid_t oid, hbool_t flag_val);
635 H5_DLL herr_t H5O__expunge_chunks_test(const H5O_loc_t *oloc);
636 H5_DLL herr_t H5O__get_rc_test(const H5O_loc_t *oloc, unsigned *rc);
637 H5_DLL herr_t H5O__msg_get_chunkno_test(hid_t oid, unsigned msg_type, unsigned *chunk_num);
638 H5_DLL herr_t H5O__msg_move_to_new_chunk_test(hid_t oid, unsigned msg_type);
639 #endif /* H5O_TESTING */
640 
641 /* Object header debugging routines */
642 #ifdef H5O_DEBUG
643 H5_DLL herr_t H5O__assert(const H5O_t *oh);
644 #endif /* H5O_DEBUG */
645 H5_DLL herr_t H5O__debug_real(H5F_t *f, H5O_t *oh, haddr_t addr, FILE *stream, int indent, int fwidth);
646 
647 #endif /* H5Opkg_H */
648