/src/hdf5/src/H5Odrvinfo.c
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 | | * Purpose: A message holding driver info settings in the superblock extension |
15 | | */ |
16 | | |
17 | | #include "H5Omodule.h" /* This source code file is part of the H5O module */ |
18 | | |
19 | | #include "H5private.h" /* Generic Functions */ |
20 | | #include "H5Eprivate.h" /* Error handling */ |
21 | | #include "H5Opkg.h" /* Object headers */ |
22 | | #include "H5MMprivate.h" /* Memory management */ |
23 | | |
24 | | static void *H5O__drvinfo_decode(H5F_t *f, H5O_t *open_oh, unsigned mesg_flags, unsigned *ioflags, |
25 | | size_t p_size, const uint8_t *p); |
26 | | static herr_t H5O__drvinfo_encode(H5F_t *f, bool disable_shared, size_t H5_ATTR_UNUSED p_size, uint8_t *p, |
27 | | const void *_mesg); |
28 | | static void *H5O__drvinfo_copy(const void *_mesg, void *_dest); |
29 | | static size_t H5O__drvinfo_size(const H5F_t *f, bool disable_shared, const void *_mesg); |
30 | | static herr_t H5O__drvinfo_reset(void *_mesg); |
31 | | static herr_t H5O__drvinfo_debug(H5F_t *f, const void *_mesg, FILE *stream, int indent, int fwidth); |
32 | | |
33 | | /* This message derives from H5O message class */ |
34 | | const H5O_msg_class_t H5O_MSG_DRVINFO[1] = {{ |
35 | | H5O_DRVINFO_ID, /*message id number */ |
36 | | "driver info", /*message name for debugging */ |
37 | | sizeof(H5O_drvinfo_t), /*native message size */ |
38 | | 0, /* messages are shareable? */ |
39 | | H5O__drvinfo_decode, /*decode message */ |
40 | | H5O__drvinfo_encode, /*encode message */ |
41 | | H5O__drvinfo_copy, /*copy the native value */ |
42 | | H5O__drvinfo_size, /*raw message size */ |
43 | | H5O__drvinfo_reset, /*free internal memory */ |
44 | | NULL, /* free method */ |
45 | | NULL, /* file delete method */ |
46 | | NULL, /* link method */ |
47 | | NULL, /*set share method */ |
48 | | NULL, /*can share method */ |
49 | | NULL, /* pre copy native value to file */ |
50 | | NULL, /* copy native value to file */ |
51 | | NULL, /* post copy native value to file */ |
52 | | NULL, /* get creation index */ |
53 | | NULL, /* set creation index */ |
54 | | H5O__drvinfo_debug /*debug the message */ |
55 | | }}; |
56 | | |
57 | | /* Current version of driver info information */ |
58 | 0 | #define H5O_DRVINFO_VERSION 0 |
59 | | |
60 | | /*------------------------------------------------------------------------- |
61 | | * Function: H5O__drvinfo_decode |
62 | | * |
63 | | * Purpose: Decode a shared message table message and return a pointer |
64 | | * to a newly allocated H5O_drvinfo_t struct. |
65 | | * |
66 | | * Return: Success: Pointer to new message in native struct |
67 | | * Failure: NULL |
68 | | *------------------------------------------------------------------------- |
69 | | */ |
70 | | static void * |
71 | | H5O__drvinfo_decode(H5F_t H5_ATTR_UNUSED *f, H5O_t H5_ATTR_UNUSED *open_oh, |
72 | | unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, size_t p_size, |
73 | | const uint8_t *p) |
74 | 0 | { |
75 | 0 | H5O_drvinfo_t *mesg = NULL; /* Native message */ |
76 | 0 | const uint8_t *p_end = p + p_size - 1; /* End of the p buffer */ |
77 | 0 | void *ret_value = NULL; |
78 | |
|
79 | 0 | FUNC_ENTER_PACKAGE |
80 | |
|
81 | 0 | assert(f); |
82 | 0 | assert(p); |
83 | | |
84 | | /* Version of message */ |
85 | 0 | if (H5_IS_BUFFER_OVERFLOW(p, 1, p_end)) |
86 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); |
87 | 0 | if (*p++ != H5O_DRVINFO_VERSION) |
88 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message"); |
89 | | |
90 | | /* Allocate space for message */ |
91 | 0 | if (NULL == (mesg = (H5O_drvinfo_t *)H5MM_calloc(sizeof(H5O_drvinfo_t)))) |
92 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info message"); |
93 | | |
94 | | /* Retrieve driver name */ |
95 | 0 | if (H5_IS_BUFFER_OVERFLOW(p, 8, p_end)) |
96 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); |
97 | 0 | H5MM_memcpy(mesg->name, p, 8); |
98 | 0 | mesg->name[8] = '\0'; |
99 | 0 | p += 8; |
100 | | |
101 | | /* Decode buffer size */ |
102 | 0 | if (H5_IS_BUFFER_OVERFLOW(p, 2, p_end)) |
103 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); |
104 | 0 | UINT16DECODE(p, mesg->len); |
105 | 0 | if (0 == mesg->len) |
106 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "message length can't be zero"); |
107 | | |
108 | | /* Allocate space for buffer */ |
109 | 0 | if (NULL == (mesg->buf = (uint8_t *)H5MM_malloc(mesg->len))) |
110 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for driver info buffer"); |
111 | | |
112 | | /* Copy encoded driver info into buffer */ |
113 | 0 | if (H5_IS_BUFFER_OVERFLOW(p, mesg->len, p_end)) |
114 | 0 | HGOTO_ERROR(H5E_OHDR, H5E_OVERFLOW, NULL, "ran off end of input buffer while decoding"); |
115 | 0 | H5MM_memcpy(mesg->buf, p, mesg->len); |
116 | | |
117 | | /* Set return value */ |
118 | 0 | ret_value = (void *)mesg; |
119 | |
|
120 | 0 | done: |
121 | 0 | if (!ret_value && mesg) { |
122 | 0 | H5MM_xfree(mesg->buf); |
123 | 0 | H5MM_xfree(mesg); |
124 | 0 | } |
125 | |
|
126 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
127 | 0 | } /* end H5O__drvinfo_decode() */ |
128 | | |
129 | | /*------------------------------------------------------------------------- |
130 | | * Function: H5O__drvinfo_encode |
131 | | * |
132 | | * Purpose: Encode a v1 B-tree 'K' value message. |
133 | | * |
134 | | * Return: Non-negative on success/Negative on failure |
135 | | * |
136 | | *------------------------------------------------------------------------- |
137 | | */ |
138 | | static herr_t |
139 | | H5O__drvinfo_encode(H5F_t H5_ATTR_UNUSED *f, bool H5_ATTR_UNUSED disable_shared, size_t H5_ATTR_UNUSED p_size, |
140 | | uint8_t *p, const void *_mesg) |
141 | 0 | { |
142 | 0 | const H5O_drvinfo_t *mesg = (const H5O_drvinfo_t *)_mesg; |
143 | |
|
144 | 0 | FUNC_ENTER_PACKAGE_NOERR |
145 | | |
146 | | /* Sanity check */ |
147 | 0 | assert(f); |
148 | 0 | assert(p); |
149 | 0 | assert(mesg); |
150 | | |
151 | | /* Store version, driver name, buffer length, & encoded buffer */ |
152 | 0 | *p++ = H5O_DRVINFO_VERSION; |
153 | 0 | H5MM_memcpy(p, mesg->name, 8); |
154 | 0 | p += 8; |
155 | 0 | assert(mesg->len <= 65535); |
156 | 0 | UINT16ENCODE(p, mesg->len); |
157 | 0 | H5MM_memcpy(p, mesg->buf, mesg->len); |
158 | |
|
159 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
160 | 0 | } /* end H5O__drvinfo_encode() */ |
161 | | |
162 | | /*------------------------------------------------------------------------- |
163 | | * Function: H5O__drvinfo_copy |
164 | | * |
165 | | * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if |
166 | | * necessary. |
167 | | * |
168 | | * Return: Success: Ptr to _DEST |
169 | | * Failure: NULL |
170 | | * |
171 | | *------------------------------------------------------------------------- |
172 | | */ |
173 | | static void * |
174 | | H5O__drvinfo_copy(const void *_mesg, void *_dest) |
175 | 0 | { |
176 | 0 | const H5O_drvinfo_t *mesg = (const H5O_drvinfo_t *)_mesg; |
177 | 0 | H5O_drvinfo_t *dest = (H5O_drvinfo_t *)_dest; |
178 | 0 | void *ret_value = NULL; /* Return value */ |
179 | |
|
180 | 0 | FUNC_ENTER_PACKAGE |
181 | | |
182 | | /* Sanity check */ |
183 | 0 | assert(mesg); |
184 | |
|
185 | 0 | if (!dest && NULL == (dest = (H5O_drvinfo_t *)H5MM_malloc(sizeof(H5O_drvinfo_t)))) |
186 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, |
187 | 0 | "memory allocation failed for shared message table message"); |
188 | | |
189 | | /* Shallow copy the fields */ |
190 | 0 | *dest = *mesg; |
191 | | |
192 | | /* Copy the buffer */ |
193 | 0 | if (NULL == (dest->buf = (uint8_t *)H5MM_malloc(mesg->len))) { |
194 | 0 | if (dest != _dest) |
195 | 0 | dest = (H5O_drvinfo_t *)H5MM_xfree(dest); |
196 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); |
197 | 0 | } /* end if */ |
198 | 0 | H5MM_memcpy(dest->buf, mesg->buf, mesg->len); |
199 | | |
200 | | /* Set return value */ |
201 | 0 | ret_value = dest; |
202 | |
|
203 | 0 | done: |
204 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
205 | 0 | } /* end H5O__drvinfo_copy() */ |
206 | | |
207 | | /*------------------------------------------------------------------------- |
208 | | * Function: H5O__drvinfo_size |
209 | | * |
210 | | * Purpose: Returns the size of the raw message in bytes not counting the |
211 | | * message type or size fields, but only the data fields. |
212 | | * |
213 | | * Return: Success: Message data size in bytes w/o alignment. |
214 | | * Failure: 0 |
215 | | * |
216 | | *------------------------------------------------------------------------- |
217 | | */ |
218 | | static size_t |
219 | | H5O__drvinfo_size(const H5F_t H5_ATTR_UNUSED *f, bool H5_ATTR_UNUSED disable_shared, const void *_mesg) |
220 | 0 | { |
221 | 0 | const H5O_drvinfo_t *mesg = (const H5O_drvinfo_t *)_mesg; |
222 | 0 | size_t ret_value = 0; /* Return value */ |
223 | |
|
224 | 0 | FUNC_ENTER_PACKAGE_NOERR |
225 | | |
226 | | /* Sanity check */ |
227 | 0 | assert(f); |
228 | 0 | assert(mesg); |
229 | |
|
230 | 0 | ret_value = 1 + /* Version number */ |
231 | 0 | 8 + /* Driver name */ |
232 | 0 | 2 + /* Buffer length */ |
233 | 0 | mesg->len; /* Buffer */ |
234 | |
|
235 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
236 | 0 | } /* end H5O__drvinfo_size() */ |
237 | | |
238 | | /*------------------------------------------------------------------------- |
239 | | * Function: H5O__drvinfo_reset |
240 | | * |
241 | | * Purpose: Frees internal pointers and resets the message to an |
242 | | * initial state. |
243 | | * |
244 | | * Return: Non-negative on success/Negative on failure |
245 | | * |
246 | | *------------------------------------------------------------------------- |
247 | | */ |
248 | | static herr_t |
249 | | H5O__drvinfo_reset(void *_mesg) |
250 | 0 | { |
251 | 0 | H5O_drvinfo_t *mesg = (H5O_drvinfo_t *)_mesg; |
252 | |
|
253 | 0 | FUNC_ENTER_PACKAGE_NOERR |
254 | | |
255 | | /* check args */ |
256 | 0 | assert(mesg); |
257 | | |
258 | | /* reset */ |
259 | 0 | mesg->buf = (uint8_t *)H5MM_xfree(mesg->buf); |
260 | |
|
261 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
262 | 0 | } /* end H5O__drvinfo_reset() */ |
263 | | |
264 | | /*------------------------------------------------------------------------- |
265 | | * Function: H5O__drvinfo_debug |
266 | | * |
267 | | * Purpose: Prints debugging info for the message. |
268 | | * |
269 | | * Return: Non-negative on success/Negative on failure |
270 | | * |
271 | | *------------------------------------------------------------------------- |
272 | | */ |
273 | | static herr_t |
274 | | H5O__drvinfo_debug(H5F_t H5_ATTR_UNUSED *f, const void *_mesg, FILE *stream, int indent, int fwidth) |
275 | 0 | { |
276 | 0 | const H5O_drvinfo_t *mesg = (const H5O_drvinfo_t *)_mesg; |
277 | |
|
278 | 0 | FUNC_ENTER_PACKAGE_NOERR |
279 | | |
280 | | /* Sanity check */ |
281 | 0 | assert(f); |
282 | 0 | assert(mesg); |
283 | 0 | assert(stream); |
284 | 0 | assert(indent >= 0); |
285 | 0 | assert(fwidth >= 0); |
286 | |
|
287 | 0 | fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Driver name:", mesg->name); |
288 | 0 | fprintf(stream, "%*s%-*s %zu\n", indent, "", fwidth, "Buffer size:", mesg->len); |
289 | |
|
290 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
291 | 0 | } /* end H5O__drvinfo_debug() */ |