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 /*
15 * Programmer: Robb Matzke <matzke@llnl.gov>
16 * Tuesday, November 25, 1997
17 */
18
19 #include "H5Omodule.h" /* This source code file is part of the H5O module */
20
21
22 #include "H5private.h" /* Generic Functions */
23 #include "H5Eprivate.h" /* Error handling */
24 #include "H5Fprivate.h" /* File access */
25 #include "H5HLprivate.h" /* Local Heaps */
26 #include "H5MMprivate.h" /* Memory management */
27 #include "H5Opkg.h" /* Object headers */
28
29 /* PRIVATE PROTOTYPES */
30 static void *H5O_efl_decode(H5F_t *f, H5O_t *open_oh, unsigned mesg_flags,
31 unsigned *ioflags, size_t p_size, const uint8_t *p);
32 static herr_t H5O_efl_encode(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg);
33 static void *H5O_efl_copy(const void *_mesg, void *_dest);
34 static size_t H5O_efl_size(const H5F_t *f, hbool_t disable_shared, const void *_mesg);
35 static herr_t H5O__efl_reset(void *_mesg);
36 static void *H5O__efl_copy_file(H5F_t *file_src, void *mesg_src,
37 H5F_t *file_dst, hbool_t *recompute_size, unsigned *mesg_flags,
38 H5O_copy_t *cpy_info, void *udata);
39 static herr_t H5O__efl_debug(H5F_t *f, const void *_mesg, FILE * stream,
40 int indent, int fwidth);
41
42 /* This message derives from H5O message class */
43 const H5O_msg_class_t H5O_MSG_EFL[1] = {{
44 H5O_EFL_ID, /*message id number */
45 "external file list", /*message name for debugging */
46 sizeof(H5O_efl_t), /*native message size */
47 0, /* messages are sharable? */
48 H5O_efl_decode, /*decode message */
49 H5O_efl_encode, /*encode message */
50 H5O_efl_copy, /*copy native value */
51 H5O_efl_size, /*size of message on disk */
52 H5O__efl_reset, /*reset method */
53 NULL, /* free method */
54 NULL, /* file delete method */
55 NULL, /* link method */
56 NULL, /*set share method */
57 NULL, /*can share method */
58 NULL, /* pre copy native value to file */
59 H5O__efl_copy_file, /* copy native value to file */
60 NULL, /* post copy native value to file */
61 NULL, /* get creation index */
62 NULL, /* set creation index */
63 H5O__efl_debug /*debug the message */
64 }};
65
66 #define H5O_EFL_VERSION 1
67
68
69 /*-------------------------------------------------------------------------
70 * Function: H5O_efl_decode
71 *
72 * Purpose: Decode an external file list message and return a pointer to
73 * the message (and some other data).
74 *
75 * Return: Success: Ptr to a new message struct.
76 *
77 * Failure: NULL
78 *
79 * Programmer: Robb Matzke
80 * Tuesday, November 25, 1997
81 *
82 * Modification:
83 * Raymond Lu
84 * 11 April 2011
85 * We allow zero dimension size starting from the 1.8.7 release.
86 * The dataset size of external storage can be zero.
87 *-------------------------------------------------------------------------
88 */
89 static void *
H5O_efl_decode(H5F_t * f,H5O_t H5_ATTR_UNUSED * open_oh,unsigned H5_ATTR_UNUSED mesg_flags,unsigned H5_ATTR_UNUSED * ioflags,size_t H5_ATTR_UNUSED p_size,const uint8_t * p)90 H5O_efl_decode(H5F_t *f, H5O_t H5_ATTR_UNUSED *open_oh,
91 unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags,
92 size_t H5_ATTR_UNUSED p_size, const uint8_t *p)
93 {
94 H5O_efl_t *mesg = NULL;
95 int version;
96 const char *s = NULL;
97 H5HL_t *heap;
98 size_t u; /* Local index variable */
99 void *ret_value = NULL; /* Return value */
100
101 FUNC_ENTER_NOAPI_NOINIT
102
103 /* Check args */
104 HDassert(f);
105 HDassert(p);
106
107 if(NULL == (mesg = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))))
108 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
109
110 /* Version */
111 version = *p++;
112 if(version != H5O_EFL_VERSION)
113 HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for external file list message")
114
115 /* Reserved */
116 p += 3;
117
118 /* Number of slots */
119 UINT16DECODE(p, mesg->nalloc);
120 HDassert(mesg->nalloc>0);
121 UINT16DECODE(p, mesg->nused);
122 HDassert(mesg->nused <= mesg->nalloc);
123
124 /* Heap address */
125 H5F_addr_decode(f, &p, &(mesg->heap_addr));
126
127 #ifndef NDEBUG
128 HDassert(H5F_addr_defined(mesg->heap_addr));
129
130 if(NULL == (heap = H5HL_protect(f, mesg->heap_addr, H5AC__READ_ONLY_FLAG)))
131 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value")
132
133 s = (const char *)H5HL_offset_into(heap, 0);
134
135 HDassert(s && !*s);
136
137 if(H5HL_unprotect(heap) < 0)
138 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value")
139 heap = NULL;
140 #endif
141
142 /* Decode the file list */
143 mesg->slot = (H5O_efl_entry_t *)H5MM_calloc(mesg->nalloc * sizeof(H5O_efl_entry_t));
144 if(NULL == mesg->slot)
145 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
146
147 if(NULL == (heap = H5HL_protect(f, mesg->heap_addr, H5AC__READ_ONLY_FLAG)))
148 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value")
149 for(u = 0; u < mesg->nused; u++) {
150 /* Name */
151 H5F_DECODE_LENGTH (f, p, mesg->slot[u].name_offset);
152
153 if((s = (const char *)H5HL_offset_into(heap, mesg->slot[u].name_offset)) == NULL)
154 HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "unable to get external file name")
155 if(*s == (char)'\0')
156 HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "invalid external file name")
157 mesg->slot[u].name = H5MM_xstrdup (s);
158 HDassert(mesg->slot[u].name);
159
160 /* File offset */
161 H5F_DECODE_LENGTH (f, p, mesg->slot[u].offset);
162
163 /* Size */
164 H5F_DECODE_LENGTH (f, p, mesg->slot[u].size);
165 } /* end for */
166
167 if(H5HL_unprotect(heap) < 0)
168 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value")
169 heap = NULL;
170
171 /* Set return value */
172 ret_value = mesg;
173
174 done:
175 if(ret_value == NULL)
176 if(mesg != NULL)
177 H5MM_xfree(mesg);
178
179 FUNC_LEAVE_NOAPI(ret_value)
180 } /* end H5O_efl_decode() */
181
182
183 /*-------------------------------------------------------------------------
184 * Function: H5O_efl_encode
185 *
186 * Purpose: Encodes a message.
187 *
188 * Return: Non-negative on success/Negative on failure
189 *
190 * Programmer: Robb Matzke
191 * Tuesday, November 25, 1997
192 *
193 *-------------------------------------------------------------------------
194 */
195 static herr_t
H5O_efl_encode(H5F_t * f,hbool_t H5_ATTR_UNUSED disable_shared,uint8_t * p,const void * _mesg)196 H5O_efl_encode(H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, const void *_mesg)
197 {
198 const H5O_efl_t *mesg = (const H5O_efl_t *)_mesg;
199 size_t u; /* Local index variable */
200
201 FUNC_ENTER_NOAPI_NOINIT_NOERR
202
203 /* check args */
204 HDassert(f);
205 HDassert(mesg);
206 HDassert(p);
207
208 /* Version */
209 *p++ = H5O_EFL_VERSION;
210
211 /* Reserved */
212 *p++ = 0;
213 *p++ = 0;
214 *p++ = 0;
215
216 /* Number of slots */
217 HDassert(mesg->nalloc > 0);
218 UINT16ENCODE(p, mesg->nused); /*yes, twice*/
219 HDassert(mesg->nused > 0 && mesg->nused <= mesg->nalloc);
220 UINT16ENCODE(p, mesg->nused);
221
222 /* Heap address */
223 HDassert(H5F_addr_defined(mesg->heap_addr));
224 H5F_addr_encode(f, &p, mesg->heap_addr);
225
226 /* Encode file list */
227 for(u = 0; u < mesg->nused; u++) {
228 /*
229 * The name should have been added to the heap when the dataset was
230 * created.
231 */
232 HDassert(mesg->slot[u].name_offset);
233 H5F_ENCODE_LENGTH(f, p, mesg->slot[u].name_offset);
234 H5F_ENCODE_LENGTH(f, p, (hsize_t)mesg->slot[u].offset);
235 H5F_ENCODE_LENGTH(f, p, mesg->slot[u].size);
236 } /* end for */
237
238 FUNC_LEAVE_NOAPI(SUCCEED)
239 } /* end H5O_efl_encode() */
240
241
242 /*-------------------------------------------------------------------------
243 * Function: H5O_efl_copy
244 *
245 * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
246 * necessary.
247 *
248 * Return: Success: Ptr to _DEST
249 *
250 * Failure: NULL
251 *
252 * Programmer: Robb Matzke
253 * Tuesday, November 25, 1997
254 *
255 *-------------------------------------------------------------------------
256 */
257 static void *
H5O_efl_copy(const void * _mesg,void * _dest)258 H5O_efl_copy(const void *_mesg, void *_dest)
259 {
260 const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg;
261 H5O_efl_t *dest = (H5O_efl_t *) _dest;
262 size_t u; /* Local index variable */
263 hbool_t slot_allocated = FALSE; /* Flag to indicate that dynamic allocation has begun */
264 void *ret_value = NULL; /* Return value */
265
266 FUNC_ENTER_NOAPI_NOINIT
267
268 /* check args */
269 HDassert(mesg);
270
271 /* Allocate destination message, if necessary */
272 if(!dest && NULL == (dest = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))))
273 HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate efl message")
274
275 /* copy */
276 *dest = *mesg;
277
278 /* Deep copy allocated information */
279 if(dest->nalloc > 0) {
280 if(NULL == (dest->slot = (H5O_efl_entry_t *)H5MM_calloc(dest->nalloc * sizeof(H5O_efl_entry_t))))
281 HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate efl message slots")
282 slot_allocated = TRUE;
283 for(u = 0; u < mesg->nused; u++) {
284 dest->slot[u] = mesg->slot[u];
285 if(NULL == (dest->slot[u].name = H5MM_xstrdup(mesg->slot[u].name)))
286 HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "can't allocate efl message slot name")
287 } /* end for */
288 } /* end if */
289
290 /* Set return value */
291 ret_value = dest;
292
293 done:
294 if(NULL == ret_value) {
295 if(slot_allocated) {
296 for(u = 0; u < dest->nused; u++)
297 if(dest->slot[u].name != NULL && dest->slot[u].name != mesg->slot[u].name)
298 dest->slot[u].name = (char *)H5MM_xfree(dest->slot[u].name);
299 dest->slot = (H5O_efl_entry_t *)H5MM_xfree(dest->slot);
300 } /* end if */
301 if(NULL == _dest)
302 dest = (H5O_efl_t *)H5MM_xfree(dest);
303 } /* end if */
304
305 FUNC_LEAVE_NOAPI(ret_value)
306 } /* end H5O_efl_copy() */
307
308
309 /*-------------------------------------------------------------------------
310 * Function: H5O_efl_size
311 *
312 * Purpose: Returns the size of the raw message in bytes not counting the
313 * message type or size fields, but only the data fields. This
314 * function doesn't take into account message alignment. This
315 * function doesn't count unused slots.
316 *
317 * Return: Success: Message data size in bytes.
318 *
319 * Failure: 0
320 *
321 * Programmer: Robb Matzke
322 * Tuesday, November 25, 1997
323 *
324 *-------------------------------------------------------------------------
325 */
326 static size_t
H5O_efl_size(const H5F_t * f,hbool_t H5_ATTR_UNUSED disable_shared,const void * _mesg)327 H5O_efl_size(const H5F_t *f, hbool_t H5_ATTR_UNUSED disable_shared, const void *_mesg)
328 {
329 const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg;
330 size_t ret_value = 0;
331
332 FUNC_ENTER_NOAPI_NOINIT_NOERR
333
334 /* check args */
335 HDassert(f);
336 HDassert(mesg);
337
338 ret_value = (size_t)H5F_SIZEOF_ADDR(f) + /*heap address */
339 2 + /*slots allocated*/
340 2 + /*num slots used*/
341 4 + /*reserved */
342 mesg->nused * ((size_t)H5F_SIZEOF_SIZE(f) + /*name offset */
343 (size_t)H5F_SIZEOF_SIZE(f) + /*file offset */
344 (size_t)H5F_SIZEOF_SIZE(f)); /*file size */
345
346 FUNC_LEAVE_NOAPI(ret_value)
347 } /* end H5O_efl_size() */
348
349
350 /*-------------------------------------------------------------------------
351 * Function: H5O__efl_reset
352 *
353 * Purpose: Frees internal pointers and resets the message to an
354 * initialial state.
355 *
356 * Return: Non-negative on success/Negative on failure
357 *
358 * Programmer: Robb Matzke
359 * Tuesday, November 25, 1997
360 *
361 *-------------------------------------------------------------------------
362 */
363 static herr_t
H5O__efl_reset(void * _mesg)364 H5O__efl_reset(void *_mesg)
365 {
366 H5O_efl_t *mesg = (H5O_efl_t *) _mesg;
367 size_t u; /* Local index variable */
368
369 FUNC_ENTER_STATIC_NOERR
370
371 /* check args */
372 HDassert(mesg);
373
374 /* reset */
375 if(mesg->slot) {
376 for(u = 0; u < mesg->nused; u++) {
377 mesg->slot[u].name = (char *)H5MM_xfree(mesg->slot[u].name);
378 mesg->slot[u].name_offset = 0;
379 } /* end for */
380 mesg->slot = (H5O_efl_entry_t *)H5MM_xfree(mesg->slot);
381 } /* end if */
382 mesg->heap_addr = HADDR_UNDEF;
383 mesg->nused = mesg->nalloc = 0;
384
385 FUNC_LEAVE_NOAPI(SUCCEED)
386 } /* end H5O__efl_reset() */
387
388
389 /*-------------------------------------------------------------------------
390 * Function: H5O_efl_total_size
391 *
392 * Purpose: Return the total size of the external file list by summing
393 * the sizes of all of the files.
394 *
395 * Return: Success: Total reserved size for external data.
396 *
397 * Failure: 0
398 *
399 * Programmer: Robb Matzke
400 * Tuesday, March 3, 1998
401 *
402 *-------------------------------------------------------------------------
403 */
404 hsize_t
H5O_efl_total_size(H5O_efl_t * efl)405 H5O_efl_total_size (H5O_efl_t *efl)
406 {
407 hsize_t ret_value = 0, tmp;
408
409 FUNC_ENTER_NOAPI_NOINIT
410
411 if(efl->nused > 0 && H5O_EFL_UNLIMITED == efl->slot[efl->nused - 1].size)
412 ret_value = H5O_EFL_UNLIMITED;
413 else {
414 size_t u; /* Local index variable */
415
416 for(u = 0; u < efl->nused; u++, ret_value = tmp) {
417 tmp = ret_value + efl->slot[u].size;
418 if(tmp <= ret_value)
419 HGOTO_ERROR(H5E_EFL, H5E_OVERFLOW, 0, "total external storage size overflowed");
420 } /* end for */
421 } /* end else */
422
423 done:
424 FUNC_LEAVE_NOAPI(ret_value)
425 } /* end H5O_efl_total_size() */
426
427
428 /*-------------------------------------------------------------------------
429 * Function: H5O__efl_copy_file
430 *
431 * Purpose: Copies an efl message from _MESG to _DEST in file
432 *
433 * Return: Success: Ptr to _DEST
434 *
435 * Failure: NULL
436 *
437 * Programmer: Peter Cao
438 * September 29, 2005
439 *
440 *-------------------------------------------------------------------------
441 */
442 static void *
H5O__efl_copy_file(H5F_t H5_ATTR_UNUSED * file_src,void * mesg_src,H5F_t * file_dst,hbool_t H5_ATTR_UNUSED * recompute_size,unsigned H5_ATTR_UNUSED * mesg_flags,H5O_copy_t H5_ATTR_UNUSED * cpy_info,void H5_ATTR_UNUSED * _udata)443 H5O__efl_copy_file(H5F_t H5_ATTR_UNUSED *file_src, void *mesg_src, H5F_t *file_dst,
444 hbool_t H5_ATTR_UNUSED *recompute_size, unsigned H5_ATTR_UNUSED *mesg_flags,
445 H5O_copy_t H5_ATTR_UNUSED *cpy_info, void H5_ATTR_UNUSED *_udata)
446 {
447 H5O_efl_t *efl_src = (H5O_efl_t *) mesg_src;
448 H5O_efl_t *efl_dst = NULL;
449 H5HL_t *heap = NULL; /* Pointer to local heap for EFL file names */
450 size_t idx, size, name_offset, heap_size;
451 void *ret_value = NULL; /* Return value */
452
453 FUNC_ENTER_STATIC_TAG(H5AC__COPIED_TAG)
454
455 /* check args */
456 HDassert(efl_src);
457 HDassert(file_dst);
458
459 /* Allocate space for the destination efl */
460 if(NULL == (efl_dst = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))))
461 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
462
463 /* Copy the "top level" information */
464 HDmemcpy(efl_dst, efl_src, sizeof(H5O_efl_t));
465
466 /* Determine size needed for destination heap */
467 heap_size = H5HL_ALIGN(1); /* "empty" name */
468 for(idx = 0; idx < efl_src->nused; idx++)
469 heap_size += H5HL_ALIGN(HDstrlen(efl_src->slot[idx].name) + 1);
470
471 /* Create name heap */
472 if(H5HL_create(file_dst, heap_size, &efl_dst->heap_addr/*out*/) < 0)
473 HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, NULL, "can't create heap")
474
475 /* Pin the heap down in memory */
476 if(NULL == (heap = H5HL_protect(file_dst, efl_dst->heap_addr, H5AC__NO_FLAGS_SET)))
477 HGOTO_ERROR(H5E_EFL, H5E_PROTECT, NULL, "unable to protect EFL file name heap")
478
479 /* Insert "empty" name first */
480 if(UFAIL == (name_offset = H5HL_insert(file_dst, heap, (size_t)1, "")))
481 HGOTO_ERROR(H5E_EFL, H5E_CANTINSERT, NULL, "can't insert file name into heap")
482 HDassert(0 == name_offset);
483
484 /* allocate array of external file entries */
485 if(efl_src->nalloc > 0) {
486 size = efl_src->nalloc * sizeof(H5O_efl_entry_t);
487 if((efl_dst->slot = (H5O_efl_entry_t *)H5MM_calloc(size)) == NULL)
488 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
489
490 /* copy content from the source. Need to update later */
491 HDmemcpy(efl_dst->slot, efl_src->slot, size);
492 } /* end if */
493
494 /* copy the name from the source */
495 for(idx = 0; idx < efl_src->nused; idx++) {
496 efl_dst->slot[idx].name = H5MM_xstrdup(efl_src->slot[idx].name);
497 if(UFAIL == (efl_dst->slot[idx].name_offset = H5HL_insert(file_dst, heap,
498 HDstrlen(efl_dst->slot[idx].name) + 1, efl_dst->slot[idx].name)))
499 HGOTO_ERROR(H5E_EFL, H5E_CANTINSERT, NULL, "can't insert file name into heap")
500 } /* end for */
501
502 /* Set return value */
503 ret_value = efl_dst;
504
505 done:
506 /* Release resources */
507 if(heap && H5HL_unprotect(heap) < 0)
508 HDONE_ERROR(H5E_EFL, H5E_PROTECT, NULL, "unable to unprotect EFL file name heap")
509 if(!ret_value)
510 if(efl_dst)
511 H5MM_xfree(efl_dst);
512
513 FUNC_LEAVE_NOAPI_TAG(ret_value)
514 } /* end H5O__efl_copy_file() */
515
516
517 /*-------------------------------------------------------------------------
518 * Function: H5O__efl_debug
519 *
520 * Purpose: Prints debugging info for a message.
521 *
522 * Return: Non-negative on success/Negative on failure
523 *
524 * Programmer: Robb Matzke
525 * Tuesday, November 25, 1997
526 *
527 *-------------------------------------------------------------------------
528 */
529 static herr_t
H5O__efl_debug(H5F_t H5_ATTR_UNUSED * f,const void * _mesg,FILE * stream,int indent,int fwidth)530 H5O__efl_debug(H5F_t H5_ATTR_UNUSED *f, const void *_mesg, FILE * stream,
531 int indent, int fwidth)
532 {
533 const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg;
534 size_t u;
535
536 FUNC_ENTER_STATIC_NOERR
537
538 /* check args */
539 HDassert(f);
540 HDassert(mesg);
541 HDassert(stream);
542 HDassert(indent >= 0);
543 HDassert(fwidth >= 0);
544
545 HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
546 "Heap address:", mesg->heap_addr);
547
548 HDfprintf(stream, "%*s%-*s %u/%u\n", indent, "", fwidth,
549 "Slots used/allocated:",
550 mesg->nused, mesg->nalloc);
551
552 for(u = 0; u < mesg->nused; u++) {
553 char buf[64];
554
555 HDsnprintf(buf, sizeof(buf), "File %u", (unsigned)u);
556 HDfprintf(stream, "%*s%s:\n", indent, "", buf);
557
558 HDfprintf(stream, "%*s%-*s \"%s\"\n", indent+3, "", MAX (fwidth-3, 0),
559 "Name:",
560 mesg->slot[u].name);
561
562 HDfprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX (fwidth-3, 0),
563 "Name offset:",
564 (unsigned long)(mesg->slot[u].name_offset));
565
566 HDfprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX (fwidth-3, 0),
567 "Offset of data in file:",
568 (unsigned long)(mesg->slot[u].offset));
569
570 HDfprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX (fwidth-3, 0),
571 "Bytes reserved for data:",
572 (unsigned long)(mesg->slot[u].size));
573 } /* end for */
574
575 FUNC_LEAVE_NOAPI(SUCCEED)
576 } /* end H5O__efl_debug() */
577
578