Line | Count | Source (jump to first uncovered line) |
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 COPYING 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: H5Oginfo.c |
16 | | * |
17 | | * Purpose: Group Information messages |
18 | | * |
19 | | *------------------------------------------------------------------------- |
20 | | */ |
21 | | |
22 | | #include "H5Omodule.h" /* This source code file is part of the H5O module */ |
23 | | |
24 | | #include "H5private.h" /* Generic Functions */ |
25 | | #include "H5Eprivate.h" /* Error handling */ |
26 | | #include "H5FLprivate.h" /* Free lists */ |
27 | | #include "H5Opkg.h" /* Object headers */ |
28 | | |
29 | | /* PRIVATE PROTOTYPES */ |
30 | | static void *H5O__ginfo_decode(H5F_t *f, H5O_t *open_oh, unsigned mesg_flags, unsigned *ioflags, |
31 | | size_t p_size, const uint8_t *p); |
32 | | static herr_t H5O__ginfo_encode(H5F_t *f, bool disable_shared, size_t H5_ATTR_UNUSED p_size, uint8_t *p, |
33 | | const void *_mesg); |
34 | | static void *H5O__ginfo_copy(const void *_mesg, void *_dest); |
35 | | static size_t H5O__ginfo_size(const H5F_t *f, bool disable_shared, const void *_mesg); |
36 | | static herr_t H5O__ginfo_free(void *_mesg); |
37 | | static herr_t H5O__ginfo_debug(H5F_t *f, const void *_mesg, FILE *stream, int indent, int fwidth); |
38 | | |
39 | | /* This message derives from H5O message class */ |
40 | | const H5O_msg_class_t H5O_MSG_GINFO[1] = {{ |
41 | | H5O_GINFO_ID, /*message id number */ |
42 | | "ginfo", /*message name for debugging */ |
43 | | sizeof(H5O_ginfo_t), /*native message size */ |
44 | | 0, /* messages are shareable? */ |
45 | | H5O__ginfo_decode, /*decode message */ |
46 | | H5O__ginfo_encode, /*encode message */ |
47 | | H5O__ginfo_copy, /*copy the native value */ |
48 | | H5O__ginfo_size, /*size of symbol table entry */ |
49 | | NULL, /*default reset method */ |
50 | | H5O__ginfo_free, /* free method */ |
51 | | NULL, /* file delete method */ |
52 | | NULL, /* link method */ |
53 | | NULL, /*set share method */ |
54 | | NULL, /*can share method */ |
55 | | NULL, /* pre copy native value to file */ |
56 | | NULL, /* copy native value to file */ |
57 | | NULL, /* post copy native value to file */ |
58 | | NULL, /* get creation index */ |
59 | | NULL, /* set creation index */ |
60 | | H5O__ginfo_debug /*debug the message */ |
61 | | }}; |
62 | | |
63 | | /* Current version of group info information */ |
64 | 0 | #define H5O_GINFO_VERSION 0 |
65 | | |
66 | | /* Flags for group info flag encoding */ |
67 | 0 | #define H5O_GINFO_STORE_PHASE_CHANGE 0x01 |
68 | 0 | #define H5O_GINFO_STORE_EST_ENTRY_INFO 0x02 |
69 | 0 | #define H5O_GINFO_ALL_FLAGS (H5O_GINFO_STORE_PHASE_CHANGE | H5O_GINFO_STORE_EST_ENTRY_INFO) |
70 | | |
71 | | /* Declare a free list to manage the H5O_ginfo_t struct */ |
72 | | H5FL_DEFINE_STATIC(H5O_ginfo_t); |
73 | | |
74 | | /*------------------------------------------------------------------------- |
75 | | * Function: H5O__ginfo_decode |
76 | | * |
77 | | * Purpose: Decode a message and return a pointer to |
78 | | * a newly allocated one. |
79 | | * |
80 | | * Return: Success: Pointer to new message in native order |
81 | | * Failure: NULL |
82 | | *------------------------------------------------------------------------- |
83 | | */ |
84 | | static void * |
85 | | H5O__ginfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, |
86 | | unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, const uint8_t *p) |
87 | 0 | { |
88 | 0 | H5O_ginfo_t *ginfo = NULL; /* Pointer to group information message */ |
89 | 0 | unsigned char flags; /* Flags for encoding group info */ |
90 | 0 | const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ |
91 | 0 | void *ret_value = NULL; |
92 | |
|
93 | 0 | FUNC_ENTER_PACKAGE |
94 | |
|
95 | 0 | assert(f); |
96 | 0 | assert(p); |
97 | | |
98 | | /* Version of message */ |
99 | 0 | if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) |
100 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); |
101 | 0 | if (*p++ != H5O_GINFO_VERSION) |
102 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message"); |
103 | | |
104 | | /* Allocate space for message */ |
105 | 0 | if (NULL == (ginfo = H5FL_CALLOC(H5O_ginfo_t))) |
106 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); |
107 | | |
108 | | /* Get the flags for the group */ |
109 | 0 | if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) |
110 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); |
111 | | |
112 | 0 | flags = *p++; |
113 | 0 | if (flags & ~H5O_GINFO_ALL_FLAGS) |
114 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad flag value for message"); |
115 | 0 | ginfo->store_link_phase_change = (flags & H5O_GINFO_STORE_PHASE_CHANGE) ? true : false; |
116 | 0 | ginfo->store_est_entry_info = (flags & H5O_GINFO_STORE_EST_ENTRY_INFO) ? true : false; |
117 | | |
118 | | /* Get the max. # of links to store compactly & the min. # of links to store densely */ |
119 | 0 | if (ginfo->store_link_phase_change) { |
120 | 0 | if (H5_IS_BUFFER_OVERFLOW(p, 2 * 2, p_end)) |
121 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); |
122 | 0 | UINT16DECODE(p, ginfo->max_compact); |
123 | 0 | UINT16DECODE(p, ginfo->min_dense); |
124 | 0 | } |
125 | 0 | else { |
126 | 0 | ginfo->max_compact = H5G_CRT_GINFO_MAX_COMPACT; |
127 | 0 | ginfo->min_dense = H5G_CRT_GINFO_MIN_DENSE; |
128 | 0 | } |
129 | | |
130 | | /* Get the estimated # of entries & name lengths */ |
131 | 0 | if (ginfo->store_est_entry_info) { |
132 | 0 | if (H5_IS_BUFFER_OVERFLOW(p, 2 * 2, p_end)) |
133 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); |
134 | 0 | UINT16DECODE(p, ginfo->est_num_entries); |
135 | 0 | UINT16DECODE(p, ginfo->est_name_len); |
136 | 0 | } |
137 | 0 | else { |
138 | 0 | ginfo->est_num_entries = H5G_CRT_GINFO_EST_NUM_ENTRIES; |
139 | 0 | ginfo->est_name_len = H5G_CRT_GINFO_EST_NAME_LEN; |
140 | 0 | } |
141 | | |
142 | | /* Set return value */ |
143 | 0 | ret_value = ginfo; |
144 | |
|
145 | 0 | done: |
146 | 0 | if (!ret_value && ginfo) |
147 | 0 | H5FL_FREE(H5O_ginfo_t, ginfo); |
148 | |
|
149 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
150 | 0 | } /* end H5O__ginfo_decode() */ |
151 | | |
152 | | /*------------------------------------------------------------------------- |
153 | | * Function: H5O__ginfo_encode |
154 | | * |
155 | | * Purpose: Encodes a message. |
156 | | * |
157 | | * Return: Non-negative on success/Negative on failure |
158 | | * |
159 | | *------------------------------------------------------------------------- |
160 | | */ |
161 | | static herr_t |
162 | | H5O__ginfo_encode(H5F_t H5_ATTR_UNUSED *f, bool H5_ATTR_UNUSED disable_shared, size_t H5_ATTR_UNUSED p_size, |
163 | | uint8_t *p, const void *_mesg) |
164 | 0 | { |
165 | 0 | const H5O_ginfo_t *ginfo = (const H5O_ginfo_t *)_mesg; |
166 | 0 | unsigned char flags = 0; /* Flags for encoding group info */ |
167 | |
|
168 | 0 | FUNC_ENTER_PACKAGE_NOERR |
169 | | |
170 | | /* check args */ |
171 | 0 | assert(p); |
172 | 0 | assert(ginfo); |
173 | | |
174 | | /* Message version */ |
175 | 0 | *p++ = H5O_GINFO_VERSION; |
176 | | |
177 | | /* The flags for the group info */ |
178 | 0 | flags = (unsigned char)(ginfo->store_link_phase_change ? H5O_GINFO_STORE_PHASE_CHANGE : 0); |
179 | 0 | flags = (unsigned char)(flags | (ginfo->store_est_entry_info ? H5O_GINFO_STORE_EST_ENTRY_INFO : 0)); |
180 | 0 | *p++ = flags; |
181 | | |
182 | | /* Store the max. # of links to store compactly & the min. # of links to store densely */ |
183 | 0 | if (ginfo->store_link_phase_change) { |
184 | 0 | UINT16ENCODE(p, ginfo->max_compact); |
185 | 0 | UINT16ENCODE(p, ginfo->min_dense); |
186 | 0 | } /* end if */ |
187 | | |
188 | | /* Estimated # of entries & name lengths */ |
189 | 0 | if (ginfo->store_est_entry_info) { |
190 | 0 | UINT16ENCODE(p, ginfo->est_num_entries); |
191 | 0 | UINT16ENCODE(p, ginfo->est_name_len); |
192 | 0 | } /* end if */ |
193 | |
|
194 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
195 | 0 | } /* end H5O__ginfo_encode() */ |
196 | | |
197 | | /*------------------------------------------------------------------------- |
198 | | * Function: H5O__ginfo_copy |
199 | | * |
200 | | * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if |
201 | | * necessary. |
202 | | * |
203 | | * Return: Success: Ptr to _DEST |
204 | | * |
205 | | * Failure: NULL |
206 | | * |
207 | | *------------------------------------------------------------------------- |
208 | | */ |
209 | | static void * |
210 | | H5O__ginfo_copy(const void *_mesg, void *_dest) |
211 | 0 | { |
212 | 0 | const H5O_ginfo_t *ginfo = (const H5O_ginfo_t *)_mesg; |
213 | 0 | H5O_ginfo_t *dest = (H5O_ginfo_t *)_dest; |
214 | 0 | void *ret_value = NULL; /* Return value */ |
215 | |
|
216 | 0 | FUNC_ENTER_PACKAGE |
217 | | |
218 | | /* check args */ |
219 | 0 | assert(ginfo); |
220 | 0 | if (!dest && NULL == (dest = H5FL_MALLOC(H5O_ginfo_t))) |
221 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); |
222 | | |
223 | | /* copy */ |
224 | 0 | *dest = *ginfo; |
225 | | |
226 | | /* Set return value */ |
227 | 0 | ret_value = dest; |
228 | |
|
229 | 0 | done: |
230 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
231 | 0 | } /* end H5O__ginfo_copy() */ |
232 | | |
233 | | /*------------------------------------------------------------------------- |
234 | | * Function: H5O__ginfo_size |
235 | | * |
236 | | * Purpose: Returns the size of the raw message in bytes not counting |
237 | | * the message type or size fields, but only the data fields. |
238 | | * This function doesn't take into account alignment. |
239 | | * |
240 | | * Return: Success: Message data size in bytes without alignment. |
241 | | * |
242 | | * Failure: zero |
243 | | * |
244 | | *------------------------------------------------------------------------- |
245 | | */ |
246 | | static size_t |
247 | | H5O__ginfo_size(const H5F_t H5_ATTR_UNUSED *f, bool H5_ATTR_UNUSED disable_shared, const void *_mesg) |
248 | 0 | { |
249 | 0 | const H5O_ginfo_t *ginfo = (const H5O_ginfo_t *)_mesg; |
250 | 0 | size_t ret_value = 0; /* Return value */ |
251 | |
|
252 | 0 | FUNC_ENTER_PACKAGE_NOERR |
253 | | |
254 | | /* Set return value */ |
255 | 0 | ret_value = 1 + /* Version */ |
256 | 0 | 1 + /* Flags */ |
257 | 0 | (ginfo->store_link_phase_change ? ((size_t)(2 + /* "Max compact" links */ |
258 | 0 | 2) /* "Min dense" links */ |
259 | 0 | ) |
260 | 0 | : 0) + /* "Min dense" links */ |
261 | 0 | (ginfo->store_est_entry_info ? ((size_t)(2 + /* Estimated # of entries in group */ |
262 | 0 | 2) /* Estimated length of name of entry in group */ |
263 | 0 | ) |
264 | 0 | : 0); |
265 | |
|
266 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
267 | 0 | } /* end H5O__ginfo_size() */ |
268 | | |
269 | | /*------------------------------------------------------------------------- |
270 | | * Function: H5O__ginfo_free |
271 | | * |
272 | | * Purpose: Frees the message |
273 | | * |
274 | | * Return: Non-negative on success/Negative on failure |
275 | | * |
276 | | *------------------------------------------------------------------------- |
277 | | */ |
278 | | static herr_t |
279 | | H5O__ginfo_free(void *mesg) |
280 | 0 | { |
281 | 0 | FUNC_ENTER_PACKAGE_NOERR |
282 | |
|
283 | 0 | assert(mesg); |
284 | |
|
285 | 0 | mesg = H5FL_FREE(H5O_ginfo_t, mesg); |
286 | |
|
287 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
288 | 0 | } /* end H5O__ginfo_free() */ |
289 | | |
290 | | /*------------------------------------------------------------------------- |
291 | | * Function: H5O__ginfo_debug |
292 | | * |
293 | | * Purpose: Prints debugging info for a message. |
294 | | * |
295 | | * Return: Non-negative on success/Negative on failure |
296 | | * |
297 | | *------------------------------------------------------------------------- |
298 | | */ |
299 | | static herr_t |
300 | | H5O__ginfo_debug(H5F_t H5_ATTR_UNUSED *f, const void *_mesg, FILE *stream, int indent, int fwidth) |
301 | 0 | { |
302 | 0 | const H5O_ginfo_t *ginfo = (const H5O_ginfo_t *)_mesg; |
303 | |
|
304 | 0 | FUNC_ENTER_PACKAGE_NOERR |
305 | | |
306 | | /* check args */ |
307 | 0 | assert(f); |
308 | 0 | assert(ginfo); |
309 | 0 | assert(stream); |
310 | 0 | assert(indent >= 0); |
311 | 0 | assert(fwidth >= 0); |
312 | |
|
313 | 0 | fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Max. compact links:", ginfo->max_compact); |
314 | 0 | fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Min. dense links:", ginfo->min_dense); |
315 | 0 | fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, |
316 | 0 | "Estimated # of objects in group:", ginfo->est_num_entries); |
317 | 0 | fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, |
318 | 0 | "Estimated length of object in group's name:", ginfo->est_name_len); |
319 | |
|
320 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
321 | 0 | } /* end H5O__ginfo_debug() */ |