/*------------------------------------------------------------------------- * Function: same_contents * * Purpose: Determines whether two files are exactly the same. * * Return: Success: nonzero if same, zero if different. * * Failure: zero * * Programmer: Robb Matzke * Wednesday, March 4, 1998 * * Modifications: * *------------------------------------------------------------------------- */ static int same_contents (const char *name1, const char *name2) { int fd1, fd2; ssize_t n1, n2; char buf1[1024], buf2[1024]; fd1 = HDopen(name1, O_RDONLY, 0666); fd2 = HDopen(name2, O_RDONLY, 0666); assert(fd1 >= 0 && fd2 >= 0); while(1) { /* Asserts will catch negative return values */ n1 = HDread(fd1, buf1, sizeof(buf1)); n2 = HDread(fd2, buf2, sizeof(buf2)); assert(n1 >= 0 && (size_t)n1 <= sizeof(buf1)); assert(n2 >= 0 && (size_t)n2 <= sizeof(buf2)); assert(n1 == n2); if(n1 == 0 && n2 == 0) break; if(HDmemcmp(buf1, buf2, (size_t)n1)) { HDclose(fd1); HDclose(fd2); return 0; } } HDclose(fd1); HDclose(fd2); return 1; }
/**************************************************************** ** ** test_metadata(): Main meta-data encode/decode testing routine. ** ****************************************************************/ void test_metadata(void) { int16_t ei16 = TEST_INT16_VALUE; /* variables to hold the values to encode */ uint16_t eu16 = TEST_UINT16_VALUE; int32_t ei32 = TEST_INT32_VALUE; uint32_t eu32 = TEST_UINT32_VALUE; int16_t di16; /* variables to hold the decoded values */ uint16_t du16; int32_t di32; uint32_t du32; uint8_t *p; /* pointer into the buffer being en/de-coded */ /* Output message about test being performed */ MESSAGE(5, ("Testing Metadata Encoding/decoding\n")); /* Start by encoding the values above */ p = encode_buffer; INT16ENCODE(p, ei16); /* Encode the int16 value */ UINT16ENCODE(p, eu16); /* Encode the uint16 value */ INT32ENCODE(p, ei32); /* Encode the int32 value */ UINT32ENCODE(p, eu32); /* Encode the uint32 value */ /* Check if we got what we asked for */ if (HDmemcmp(encode_buffer, compar_buffer, sizeof(compar_buffer)) != 0) { unsigned u; /* local counting variable */ for (u = 0; u < sizeof(compar_buffer); u++) { if (compar_buffer[u] != encode_buffer[u]) TestErrPrintf("Error encoding meta-data at offset %u, wanted: %u, got: %u\n", (unsigned) u, (unsigned) compar_buffer[u], (unsigned) encode_buffer[u]); } /* end for */ } /* end if */ /* Test decoding macros */ p = encode_buffer; INT16DECODE(p, di16); /* Decode the int16 value */ UINT16DECODE(p, du16); /* Decode the uint16 value */ INT32DECODE(p, di32); /* Decode the int32 value */ UINT32DECODE(p, du32); /* Decode the uint32 value */ /* Check the values decoded */ if (di16 != TEST_INT16_VALUE) TestErrPrintf("Error decoding int16 meta-data wanted: %d, got: %d " "at %s:%d\n", (int) TEST_INT16_VALUE, (int) di16, __FILE__, __LINE__); if (du16 != TEST_UINT16_VALUE) TestErrPrintf("Error decoding uint16 meta-data wanted: %u, got: %u " "at %s:%d\n", (unsigned) TEST_UINT16_VALUE, (unsigned) du16, __FILE__, __LINE__); if (di32 != TEST_INT32_VALUE) TestErrPrintf("Error decoding int32 meta-data wanted: %ld, got: %ld " "at %s:%d\n", (long) TEST_INT32_VALUE, (long) di32, __FILE__, __LINE__); if (du32 != TEST_UINT32_VALUE) TestErrPrintf("Error decoding uint32 meta-data wanted: %lu, got: %lu " "at %s:%d\n", (unsigned long) TEST_UINT32_VALUE, (unsigned long) du32, __FILE__, __LINE__); } /* test_metadata() */
/*------------------------------------------------------------------------- * Function: H5HG_load * * Purpose: Loads a global heap collection from disk. * * Return: Success: Ptr to a global heap collection. * * Failure: NULL * * Programmer: Robb Matzke * Friday, March 27, 1998 * *------------------------------------------------------------------------- */ static H5HG_heap_t * H5HG_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1, void UNUSED * udata2) { H5HG_heap_t *heap = NULL; uint8_t *p = NULL; size_t nalloc, need; size_t max_idx = 0; /* The maximum index seen */ H5HG_heap_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI(H5HG_load, NULL) /* check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(!udata1); HDassert(!udata2); /* Read the initial 4k page */ if(NULL == (heap = H5FL_CALLOC(H5HG_heap_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") heap->addr = addr; if(NULL == (heap->chunk = H5FL_BLK_MALLOC(gheap_chunk, (size_t)H5HG_MINSIZE))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") if(H5F_block_read(f, H5FD_MEM_GHEAP, addr, (size_t)H5HG_MINSIZE, dxpl_id, heap->chunk) < 0) HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection") /* Magic number */ if(HDmemcmp(heap->chunk, H5HG_MAGIC, (size_t)H5_SIZEOF_MAGIC)) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad global heap collection signature") p = heap->chunk + H5_SIZEOF_MAGIC; /* Version */ if(H5HG_VERSION != *p++) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong version number in global heap") /* Reserved */ p += 3; /* Size */ H5F_DECODE_LENGTH(f, p, heap->size); HDassert(heap->size >= H5HG_MINSIZE); /* * If we didn't read enough in the first try, then read the rest of the * collection now. */ if(heap->size > H5HG_MINSIZE) { haddr_t next_addr = addr + (hsize_t)H5HG_MINSIZE; if(NULL == (heap->chunk = H5FL_BLK_REALLOC(gheap_chunk, heap->chunk, heap->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") if(H5F_block_read(f, H5FD_MEM_GHEAP, next_addr, (heap->size - H5HG_MINSIZE), dxpl_id, heap->chunk + H5HG_MINSIZE) < 0) HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection") } /* end if */
/*------------------------------------------------------------------------- * Function: test_extend * * Purpose: Creates an empty object and then writes to it in such a way * as to always extend the object's domain without creating * holes and without causing the object to become concave. * * Return: Success: SUCCEED * * Failure: FAIL * * Programmer: Robb Matzke * Wednesday, October 15, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t test_extend(hid_t f, const char *prefix, size_t nx, size_t ny, size_t nz) { hid_t dataset; /* Dataset ID */ hid_t fspace; /* Dataset's file dataspace */ hid_t mspace; /* Dataset's memory dataspace */ size_t i, j, k, ctr; int ndims; uint8_t *buf = NULL, *check = NULL, *whole = NULL; char dims[64], s[256], name[256]; hsize_t offset[3]; hsize_t max_corner[3]; hsize_t size[3]; hsize_t whole_size[3]; hsize_t nelmts; if (!nz) { if (!ny) { ndims = 1; ny = nz = 1; sprintf(dims, "%lu", (unsigned long) nx); } else { ndims = 2; nz = 1; sprintf(dims, "%lux%lu", (unsigned long) nx, (unsigned long) ny); } } else { ndims = 3; sprintf(dims, "%lux%lux%lu", (unsigned long) nx, (unsigned long) ny, (unsigned long) nz); } sprintf(s, "istore extend: %s", dims); TESTING(s); buf = (uint8_t *)HDmalloc(nx * ny * nz); check = (uint8_t *)HDmalloc(nx * ny * nz); whole = (uint8_t *)HDcalloc((size_t)1, nx * ny * nz); whole_size[0] = nx; whole_size[1] = ny; whole_size[2] = nz; max_corner[0] = 0; max_corner[1] = 0; max_corner[2] = 0; /* Build the new empty object */ sprintf(name, "%s_%s", prefix, dims); if ((dataset=new_object(f, name, ndims, whole_size, whole_size)) < 0) { fprintf(stderr," Cannot create %u-d object `%s'\n", ndims, name); goto error; } /* Get dataset's dataspace */ if((fspace=H5Dget_space(dataset)) < 0) TEST_ERROR; for (ctr = 0; H5VM_vector_lt_u((unsigned)ndims, max_corner, whole_size); ctr++) { /* Size and location */ if (0 == ctr) { offset[0] = offset[1] = offset[2] = 0; size[0] = size[1] = size[2] = 1; nelmts = 1; } else { for (i=0, nelmts=1; i<(size_t)ndims; i++) { if (ctr % (size_t)ndims == i) { offset[i] = max_corner[i]; size[i] = MIN(1, whole_size[i] - offset[i]); } else { offset[i] = 0; size[i] = max_corner[i]; } nelmts *= size[i]; } } #if 0 if (0 == ctr) fprintf(stderr,"\n"); fprintf(stderr," Insert: ctr=%lu, corner=(%ld", (unsigned long)ctr, (long)offset[0]); if (ndims > 1) fprintf(stderr,",%ld", (long)offset[1]); if (ndims > 2) fprintf(stderr,",%ld", (long)offset[2]); fprintf(stderr,"), size=(%lu", (unsigned long)size[0]); if (ndims > 1) fprintf(stderr,",%lu", (unsigned long)size[1]); if (ndims > 2) fprintf(stderr,",%lu", (unsigned long)size[2]); fprintf(stderr,"), %lu element%s", (unsigned long)nelmts, 1 == nelmts ? "" : "s"); if (0 == nelmts) fprintf(stderr," *SKIPPED*"); fprintf(stderr,"\n"); #endif /* Fill the source array */ if (0 == nelmts) continue; HDmemset(buf, (signed)(128+ctr), (size_t)nelmts); /* Create dataspace for selection in memory */ if((mspace=H5Screate_simple(1,&nelmts,NULL)) < 0) TEST_ERROR; /* Select region in file dataspace */ if(H5Sselect_hyperslab(fspace,H5S_SELECT_SET,offset,NULL,size,NULL) < 0) TEST_ERROR; /* Write to disk */ if (H5Dwrite(dataset, TEST_DATATYPE, mspace, fspace, H5P_DEFAULT, buf) < 0) { H5_FAILED(); fprintf(stderr," Write failed: ctr=%lu\n", (unsigned long)ctr); goto error; } /* Read from disk */ HDmemset(check, 0xff, (size_t)nelmts); if (H5Dread(dataset, TEST_DATATYPE, mspace, fspace, H5P_DEFAULT, check) < 0) { H5_FAILED(); fprintf(stderr," Read failed: ctr=%lu\n", (unsigned long)ctr); goto error; } if (HDmemcmp(buf, check, (size_t)nelmts)) { H5_FAILED(); fprintf(stderr," Read check failed: ctr=%lu\n", (unsigned long)ctr); fprintf(stderr," Wrote:\n"); print_array(buf, (size_t)size[0], (size_t)size[1], (size_t)size[2]); fprintf(stderr," Read:\n"); print_array(check, (size_t)size[0], (size_t)size[1], (size_t)size[2]); goto error; } /* Close memory dataspace */ if(H5Sclose(mspace) < 0) TEST_ERROR; /* Write to `whole' buffer for later checking */ H5VM_hyper_copy((unsigned)ndims, size, whole_size, offset, whole, /*dst*/ size, H5VM_ZERO, buf); /*src*/ /* Update max corner */ for (i=0; i<(size_t)ndims; i++) max_corner[i] = MAX(max_corner[i], offset[i]+size[i]); } /* Now read the entire array back out and check it */ HDmemset(buf, 0xff, nx * ny * nz); if (H5Dread(dataset, TEST_DATATYPE, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) { H5_FAILED(); fprintf(stderr," Read failed for whole array.\n"); goto error; } for (i=0; i<nx; i++) { for (j=0; j<ny; j++) { for (k=0; k<nz; k++) { if (whole[i*ny*nz + j*nz + k] != buf[i*ny*nz + j*nz + k]) { H5_FAILED(); fprintf(stderr," Check failed at i=%lu", (unsigned long)i); if (ndims > 1) { fprintf(stderr,", j=%lu", (unsigned long)j); } if (ndims > 2) { fprintf(stderr,", k=%lu", (unsigned long)k); } fprintf(stderr,"\n Check array is:\n"); print_array(whole, nx, ny, nz); fprintf(stderr," Value read is:\n"); print_array(buf, nx, ny, nz); goto error; } } } } /* Close dataset's dataspace */ if(H5Sclose(fspace) < 0) TEST_ERROR; /* Close dataset */ if(H5Dclose(dataset) < 0) TEST_ERROR; /* Free memory used */ HDfree(buf); HDfree(check); HDfree(whole); PASSED(); return SUCCEED; error: HDfree(buf); HDfree(check); HDfree(whole); return FAIL; }
/* * test_strpad * Tests string padding for a UTF-8 string. * Converts strings to shorter and then longer strings. * Borrows heavily from dtypes.c, but is more complicated because * the string is randomly generated. */ void test_strpad(hid_t UNUSED fid, const char *string) { /* buf is used to hold the data that H5Tconvert operates on. */ char buf[LONG_BUF_SIZE]; /* cmpbuf holds the output that H5Tconvert should produce, * to compare against the actual output. */ char cmpbuf[LONG_BUF_SIZE]; /* new_string is a slightly modified version of the UTF-8 * string to make the tests run more smoothly. */ char new_string[MAX_STRING_LENGTH + 2]; size_t length; /* Length of new_string in bytes */ size_t small_len; /* Size of the small datatype */ size_t big_len; /* Size of the larger datatype */ hid_t src_type, dst_type; herr_t ret; /* The following tests are simpler if the UTF-8 string contains * the right number of bytes (even or odd, depending on the test). * We create a 'new_string' whose length is convenient by prepending * an 'x' to 'string' when necessary. */ length = HDstrlen(string); if(length % 2 != 1) { HDstrcpy(new_string, "x"); HDstrcat(new_string, string); length++; } else { HDstrcpy(new_string, string); } /* Convert a null-terminated string to a shorter and longer null * terminated string. */ /* Create a src_type that holds the UTF-8 string and its final NULL */ big_len = length + 1; /* +1 byte for final NULL */ HDassert((2*big_len)<=sizeof(cmpbuf)); src_type = mkstr(big_len, H5T_STR_NULLTERM); CHECK(src_type, FAIL, "mkstr"); /* Create a dst_type that holds half of the UTF-8 string and a final * NULL */ small_len = (length + 1) / 2; dst_type = mkstr(small_len, H5T_STR_NULLTERM); CHECK(dst_type, FAIL, "mkstr"); /* Fill the buffer with two copies of the UTF-8 string, each with a * terminating NULL. It will look like "abcdefg\0abcdefg\0". */ strncpy(buf, new_string, big_len); strncpy(&buf[big_len], new_string, big_len); ret = H5Tconvert(src_type, dst_type, (size_t)2, buf, NULL, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tconvert"); /* After conversion, the buffer should look like * "abc\0abc\0abcdefg\0". Note that this is just what the bytes look * like; UTF-8 characters may well have been truncated. * To check that the conversion worked properly, we'll build this * string manually. */ HDstrncpy(cmpbuf, new_string, small_len - 1); cmpbuf[small_len - 1] = '\0'; HDstrncpy(&cmpbuf[small_len], new_string, small_len -1); cmpbuf[2 * small_len - 1] = '\0'; HDstrcpy(&cmpbuf[2 * small_len], new_string); VERIFY(HDmemcmp(buf, cmpbuf, 2*big_len), 0, "HDmemcmp"); /* Now convert from smaller datatype to bigger datatype. This should * leave our buffer looking like: "abc\0\0\0\0\0abc\0\0\0\0\0" */ ret = H5Tconvert(dst_type, src_type, (size_t)2, buf, NULL, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tconvert"); /* First fill the buffer with NULLs */ HDmemset(cmpbuf, '\0', (size_t)LONG_BUF_SIZE); /* Copy in the characters */ HDstrncpy(cmpbuf, new_string, small_len -1); HDstrncpy(&cmpbuf[big_len], new_string, small_len -1); VERIFY(HDmemcmp(buf, cmpbuf, 2*big_len), 0, "HDmemcmp"); ret = H5Tclose(src_type); CHECK(ret, FAIL, "H5Tclose"); ret = H5Tclose(dst_type); CHECK(ret, FAIL, "H5Tclose"); /* Now test null padding. Null-padded strings do *not* need * terminating NULLs, so the sizes of the datatypes are slightly * different and we want a string with an even number of characters. */ length = HDstrlen(string); if(length % 2 != 0) { HDstrcpy(new_string, "x"); HDstrcat(new_string, string); length++; } else { HDstrcpy(new_string, string); } /* Create a src_type that holds the UTF-8 string */ big_len = length; HDassert((2*big_len)<=sizeof(cmpbuf)); src_type = mkstr(big_len, H5T_STR_NULLPAD); CHECK(src_type, FAIL, "mkstr"); /* Create a dst_type that holds half of the UTF-8 string */ small_len = length / 2; dst_type = mkstr(small_len, H5T_STR_NULLPAD); CHECK(dst_type, FAIL, "mkstr"); /* Fill the buffer with two copies of the UTF-8 string. * It will look like "abcdefghabcdefgh". */ strncpy(buf, new_string, big_len); strncpy(&buf[big_len], new_string, big_len); ret = H5Tconvert(src_type, dst_type, (size_t)2, buf, NULL, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tconvert"); /* After conversion, the buffer should look like * "abcdabcdabcdefgh". Note that this is just what the bytes look * like; UTF-8 characters may well have been truncated. * To check that the conversion worked properly, we'll build this * string manually. */ HDstrncpy(cmpbuf, new_string, small_len); HDstrncpy(&cmpbuf[small_len], new_string, small_len); HDstrncpy(&cmpbuf[2 * small_len], new_string, big_len); VERIFY(HDmemcmp(buf, cmpbuf, 2*big_len), 0, "HDmemcmp"); /* Now convert from smaller datatype to bigger datatype. This should * leave our buffer looking like: "abcd\0\0\0\0abcd\0\0\0\0" */ ret = H5Tconvert(dst_type, src_type, (size_t)2, buf, NULL, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tconvert"); /* First fill the buffer with NULLs */ HDmemset(cmpbuf, '\0', (size_t)LONG_BUF_SIZE); /* Copy in the characters */ HDstrncpy(cmpbuf, new_string, small_len); HDstrncpy(&cmpbuf[big_len], new_string, small_len); VERIFY(HDmemcmp(buf, cmpbuf, 2*big_len), 0, "HDmemcmp"); ret = H5Tclose(src_type); CHECK(ret, FAIL, "H5Tclose"); ret = H5Tclose(dst_type); CHECK(ret, FAIL, "H5Tclose"); /* Test space padding. This is very similar to null-padding; we can use the same values of length, small_len, and big_len. */ src_type = mkstr(big_len, H5T_STR_SPACEPAD); CHECK(src_type, FAIL, "mkstr"); dst_type = mkstr(small_len, H5T_STR_SPACEPAD); CHECK(src_type, FAIL, "mkstr"); /* Fill the buffer with two copies of the UTF-8 string. * It will look like "abcdefghabcdefgh". */ HDstrcpy(buf, new_string); HDstrcpy(&buf[big_len], new_string); ret = H5Tconvert(src_type, dst_type, (size_t)2, buf, NULL, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tconvert"); /* After conversion, the buffer should look like * "abcdabcdabcdefgh". Note that this is just what the bytes look * like; UTF-8 characters may have been truncated. * To check that the conversion worked properly, we'll build this * string manually. */ HDstrncpy(cmpbuf, new_string, small_len); HDstrncpy(&cmpbuf[small_len], new_string, small_len); HDstrncpy(&cmpbuf[2 * small_len], new_string, big_len); VERIFY(HDmemcmp(buf, cmpbuf, 2*big_len), 0, "HDmemcmp"); /* Now convert from smaller datatype to bigger datatype. This should * leave our buffer looking like: "abcd abcd " */ ret = H5Tconvert(dst_type, src_type, (size_t)2, buf, NULL, H5P_DEFAULT); CHECK(ret, FAIL, "H5Tconvert"); /* First fill the buffer with spaces */ HDmemset(cmpbuf, ' ', (size_t)LONG_BUF_SIZE); /* Copy in the characters */ HDstrncpy(cmpbuf, new_string, small_len); HDstrncpy(&cmpbuf[big_len], new_string, small_len); VERIFY(HDmemcmp(buf, cmpbuf, 2*big_len), 0, "HDmemcmp"); ret = H5Tclose(src_type); CHECK(ret, FAIL, "H5Tclose"); ret = H5Tclose(dst_type); CHECK(ret, FAIL, "H5Tclose"); }
/*------------------------------------------------------------------------- * Function: H5O_load * * Purpose: Loads an object header from disk. * * Return: Success: Pointer to the new object header. * * Failure: NULL * * Programmer: Robb Matzke * [email protected] * Aug 5 1997 * *------------------------------------------------------------------------- */ static H5O_t * H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, void UNUSED * _udata2) { H5O_t *oh = NULL; /* Object header read in */ uint8_t read_buf[H5O_SPEC_READ_SIZE]; /* Buffer for speculative read */ const uint8_t *p; /* Pointer into buffer to decode */ size_t spec_read_size; /* Size of buffer to speculatively read in */ size_t prefix_size; /* Size of object header prefix */ unsigned nmesgs; /* Total # of messages in this object header */ unsigned curmesg = 0; /* Current message being decoded in object header */ unsigned merged_null_msgs = 0; /* Number of null messages merged together */ haddr_t chunk_addr; /* Address of first chunk */ size_t chunk_size; /* Size of first chunk */ haddr_t eoa; /* Relative end of file address */ H5O_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_load, NULL) /* check args */ HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(!_udata1); HDassert(!_udata2); /* Make certain we don't speculatively read off the end of the file */ if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, H5FD_MEM_OHDR))) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to determine file size") /* Compute the size of the speculative object header buffer */ H5_ASSIGN_OVERFLOW(spec_read_size, MIN(eoa - addr, H5O_SPEC_READ_SIZE), /* From: */ hsize_t, /* To: */ size_t); /* Attempt to speculatively read both object header prefix and first chunk */ if(H5F_block_read(f, H5FD_MEM_OHDR, addr, spec_read_size, dxpl_id, read_buf) < 0) HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header") p = read_buf; /* allocate ohdr and init chunk list */ if(NULL == (oh = H5FL_CALLOC(H5O_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* File-specific, non-stored information */ oh->sizeof_size = H5F_SIZEOF_SIZE(f); oh->sizeof_addr = H5F_SIZEOF_ADDR(f); /* Check for magic number */ /* (indicates version 2 or later) */ if(!HDmemcmp(p, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* Magic number */ p += H5_SIZEOF_MAGIC; /* Version */ oh->version = *p++; if(H5O_VERSION_2 != oh->version) HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number") /* Flags */ oh->flags = *p++; if(oh->flags & ~H5O_HDR_ALL_FLAGS) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "unknown object header status flag(s)") /* Number of messages (to allocate initially) */ nmesgs = 1; /* Number of links to object (unless overridden by refcount message) */ oh->nlink = 1; /* Time fields */ if(oh->flags & H5O_HDR_STORE_TIMES) { uint32_t tmp; /* Temporary value */ UINT32DECODE(p, tmp); oh->atime = (time_t)tmp; UINT32DECODE(p, tmp); oh->mtime = (time_t)tmp; UINT32DECODE(p, tmp); oh->ctime = (time_t)tmp; UINT32DECODE(p, tmp); oh->btime = (time_t)tmp; } /* end if */ else oh->atime = oh->mtime = oh->ctime = oh->btime = 0; /* Attribute fields */ if(oh->flags & H5O_HDR_ATTR_STORE_PHASE_CHANGE) { UINT16DECODE(p, oh->max_compact); UINT16DECODE(p, oh->min_dense); if(oh->max_compact < oh->min_dense) HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header attribute phase change values") } /* end if */
/*------------------------------------------------------------------------- * Function: main * * Usage: debug FILENAME [OFFSET] * * Return: Success: exit (0) * * Failure: exit (non-zero) * * Programmer: Robb Matzke * [email protected] * Jul 18 1997 * *------------------------------------------------------------------------- */ int main(int argc, char *argv[]) { hid_t fid, fapl, dxpl; H5F_t *f; haddr_t addr = 0, extra = 0, extra2 = 0, extra3 = 0, extra4 = 0; uint8_t sig[H5F_SIGNATURE_LEN]; size_t u; H5E_auto2_t func; void *edata; herr_t status = SUCCEED; if(argc == 1) { HDfprintf(stderr, "Usage: %s filename [signature-addr [extra]]\n", argv[0]); HDexit(1); } /* end if */ /* Initialize the library */ if(H5open() < 0) { HDfprintf(stderr, "cannot initialize the library\n"); HDexit(1); } /* end if */ /* Disable error reporting */ H5Eget_auto2(H5E_DEFAULT, &func, &edata); H5Eset_auto2(H5E_DEFAULT, NULL, NULL); /* * Open the file and get the file descriptor. */ dxpl = H5AC_ind_read_dxpl_id; if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) { HDfprintf(stderr, "cannot create file access property list\n"); HDexit(1); } /* end if */ if(HDstrchr(argv[1], '%')) if(H5Pset_fapl_family (fapl, (hsize_t)0, H5P_DEFAULT) < 0) { fprintf(stderr, "cannot set file access property list\n"); HDexit(1); } if((fid = H5Fopen(argv[1], H5F_ACC_RDONLY, fapl)) < 0) { HDfprintf(stderr, "cannot open file\n"); HDexit(1); } /* end if */ if(NULL == (f = (H5F_t *)H5I_object(fid))) { HDfprintf(stderr, "cannot obtain H5F_t pointer\n"); HDexit(2); } /* end if */ /* Ignore metadata tags while using h5debug */ if(H5AC_ignore_tags(f) < 0) { HDfprintf(stderr, "cannot ignore metadata tags\n"); HDexit(1); } /* * Parse command arguments. */ if(argc > 2) addr = (haddr_t)HDstrtoll(argv[2], NULL, 0); if(argc > 3) extra = (haddr_t)HDstrtoll(argv[3], NULL, 0); if(argc > 4) extra2 = (haddr_t)HDstrtoll(argv[4], NULL, 0); if(argc > 5) extra3 = (haddr_t)HDstrtoll(argv[5], NULL, 0); if(argc > 6) extra4 = (haddr_t)HDstrtoll(argv[6], NULL, 0); /* * Read the signature at the specified file position. */ HDfprintf(stdout, "Reading signature at address %a (rel)\n", addr); if(H5F_block_read(f, H5FD_MEM_SUPER, addr, sizeof(sig), dxpl, sig) < 0) { HDfprintf(stderr, "cannot read signature\n"); HDexit(3); } if(!HDmemcmp(sig, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN)) { /* * Debug the file's super block. */ status = H5F_debug(f, stdout, 0, VCOL); } else if(!HDmemcmp(sig, H5HL_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a local heap. */ status = H5HL_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL); } else if(!HDmemcmp (sig, H5HG_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a global heap collection. */ status = H5HG_debug (f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL); } else if(!HDmemcmp(sig, H5G_NODE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a symbol table node. */ /* Check for extra parameters */ if(extra == 0) { HDfprintf(stderr, "\nWarning: Providing the group's local heap address will give more information\n"); HDfprintf(stderr, "Symbol table node usage:\n"); HDfprintf(stderr, "\th5debug <filename> <Symbol table node address> <address of local heap>\n\n"); } /* end if */ status = H5G_node_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra); } else if(!HDmemcmp(sig, H5B_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a B-tree. B-trees are debugged through the B-tree * subclass. The subclass identifier is the byte immediately * after the B-tree signature. */ H5B_subid_t subtype = (H5B_subid_t)sig[H5_SIZEOF_MAGIC]; unsigned ndims; uint32_t dim[H5O_LAYOUT_NDIMS]; switch(subtype) { case H5B_SNODE_ID: /* Check for extra parameters */ if(extra == 0) { HDfprintf(stderr, "\nWarning: Providing the group's local heap address will give more information\n"); HDfprintf(stderr, "B-tree symbol table node usage:\n"); HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <address of local heap>\n\n"); HDexit(4); } /* end if */ status = H5G_node_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra); break; case H5B_CHUNK_ID: /* Check for extra parameters */ if(extra == 0) { HDfprintf(stderr, "ERROR: Need number of dimensions of chunk in order to dump chunk B-tree node\n"); HDfprintf(stderr, "B-tree chunked storage node usage:\n"); HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <# of dimensions> <slowest chunk dim>...<fastest chunk dim>\n"); HDexit(4); } /* end if */ /* Build array of chunk dimensions */ ndims = (unsigned)extra; dim[0] = (uint32_t)extra2; if(ndims > 1) dim[1] = (uint32_t)extra3; if(ndims > 2) dim[2] = (uint32_t)extra4; /* Check for dimension error */ if(ndims > 3) { HDfprintf(stderr, "ERROR: Only 3 dimensions support currently (fix h5debug)\n"); HDfprintf(stderr, "B-tree chunked storage node usage:\n"); HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <# of dimensions> <slowest chunk dim>...<fastest chunk dim>\n"); HDexit(4); } /* end for */ for(u = 0; u < ndims; u++) if(0 == dim[u]) { HDfprintf(stderr, "ERROR: Chunk dimensions should be >0\n"); HDfprintf(stderr, "B-tree chunked storage node usage:\n"); HDfprintf(stderr, "\th5debug <filename> <B-tree node address> <# of dimensions> <slowest chunk dim>...<fastest chunk dim>\n"); HDexit(4); } /* end if */ /* Set the last dimension (the element size) to zero */ dim[ndims] = 0; status = H5D_btree_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, ndims, dim); break; case H5B_NUM_BTREE_ID: default: HDfprintf(stderr, "Unknown v1 B-tree subtype %u\n", (unsigned)(subtype)); HDexit(4); } } else if(!HDmemcmp(sig, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a v2 B-tree header. */ const H5B2_class_t *cls = get_H5B2_class(sig); HDassert(cls); if((cls == H5D_BT2 || cls == H5D_BT2_FILT) && extra == 0) { HDfprintf(stderr, "ERROR: Need v2 B-tree header address and object header address containing the layout message in order to dump header\n"); HDfprintf(stderr, "v2 B-tree hdr usage:\n"); HDfprintf(stderr, "\th5debug <filename> <v2 B-tree header address> <object header address>\n"); HDexit(4); } /* end if */ status = H5B2__hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, (haddr_t)extra); } else if(!HDmemcmp(sig, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a v2 B-tree internal node. */ const H5B2_class_t *cls = get_H5B2_class(sig); HDassert(cls); /* Check for enough valid parameters */ if((cls == H5D_BT2 || cls == H5D_BT2_FILT) && (extra == 0 || extra2 == 0 || extra3 == 0 || extra4 == 0)) { fprintf(stderr, "ERROR: Need v2 B-tree header address, the node's number of records, depth, and object header address containing the layout message in order to dump internal node\n"); fprintf(stderr, "NOTE: Leaf nodes are depth 0, the internal nodes above them are depth 1, etc.\n"); fprintf(stderr, "v2 B-tree internal node usage:\n"); fprintf(stderr, "\th5debug <filename> <internal node address> <v2 B-tree header address> <number of records> <depth> <object header address>\n"); HDexit(4); } else if(extra == 0 || extra2 == 0 || extra3 == 0) { HDfprintf(stderr, "ERROR: Need v2 B-tree header address and the node's number of records and depth in order to dump internal node\n"); HDfprintf(stderr, "NOTE: Leaf nodes are depth 0, the internal nodes above them are depth 1, etc.\n"); HDfprintf(stderr, "v2 B-tree internal node usage:\n"); HDfprintf(stderr, "\th5debug <filename> <internal node address> <v2 B-tree header address> <number of records> <depth>\n"); HDexit(4); } /* end if */ status = H5B2__int_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, (unsigned)extra3, (haddr_t)extra4); } else if(!HDmemcmp(sig, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a v2 B-tree leaf node. */ const H5B2_class_t *cls = get_H5B2_class(sig); HDassert(cls); /* Check for enough valid parameters */ if((cls == H5D_BT2 || cls == H5D_BT2_FILT) && (extra == 0 || extra2 == 0 || extra3 == 0 )) { fprintf(stderr, "ERROR: Need v2 B-tree header address, number of records, and object header address containing the layout message in order to dump leaf node\n"); fprintf(stderr, "v2 B-tree leaf node usage:\n"); fprintf(stderr, "\th5debug <filename> <leaf node address> <v2 B-tree header address> <number of records> <object header address>\n"); HDexit(4); } else if(extra == 0 || extra2 == 0) { HDfprintf(stderr, "ERROR: Need v2 B-tree header address and number of records in order to dump leaf node\n"); HDfprintf(stderr, "v2 B-tree leaf node usage:\n"); HDfprintf(stderr, "\th5debug <filename> <leaf node address> <v2 B-tree header address> <number of records>\n"); HDexit(4); } /* end if */ status = H5B2__leaf_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, (haddr_t)extra3); } else if(!HDmemcmp(sig, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a fractal heap header. */ status = H5HF_hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL); } else if(!HDmemcmp(sig, H5HF_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a fractal heap direct block. */ /* Check for enough valid parameters */ if(extra == 0 || extra2 == 0) { HDfprintf(stderr, "ERROR: Need fractal heap header address and size of direct block in order to dump direct block\n"); HDfprintf(stderr, "Fractal heap direct block usage:\n"); HDfprintf(stderr, "\th5debug <filename> <direct block address> <heap header address> <size of direct block>\n"); HDexit(4); } /* end if */ status = H5HF_dblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra, (size_t)extra2); } else if(!HDmemcmp(sig, H5HF_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a fractal heap indirect block. */ /* Check for enough valid parameters */ if(extra == 0 || extra2 == 0) { HDfprintf(stderr, "ERROR: Need fractal heap header address and number of rows in order to dump indirect block\n"); HDfprintf(stderr, "Fractal heap indirect block usage:\n"); HDfprintf(stderr, "\th5debug <filename> <indirect block address> <heap header address> <number of rows>\n"); HDexit(4); } /* end if */ status = H5HF_iblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra, (unsigned)extra2); } else if(!HDmemcmp(sig, H5FS_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a free space header. */ status = H5FS_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL); } else if(!HDmemcmp(sig, H5FS_SINFO_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug free space serialized sections. */ /* Check for enough valid parameters */ if(extra == 0 || extra2 == 0) { HDfprintf(stderr, "ERROR: Need free space header address and client address in order to dump serialized sections\n"); HDfprintf(stderr, "Free space serialized sections usage:\n"); HDfprintf(stderr, "\th5debug <filename> <serialized sections address> <free space header address> <client address>\n"); HDexit(4); } /* end if */ status = H5FS_sects_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, extra, extra2); } else if(!HDmemcmp(sig, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug shared message master table. */ status = H5SM_table_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, (unsigned) UFAIL, (unsigned) UFAIL); } else if(!HDmemcmp(sig, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug shared message list index. */ /* Check for enough valid parameters */ if(extra == 0) { HDfprintf(stderr, "ERROR: Need shared message header address in order to shared message list\n"); HDfprintf(stderr, "Shared message list usage:\n"); HDfprintf(stderr, "\th5debug <filename> <shared message list address> <shared message header address>\n"); HDexit(4); } /* end if */ status = H5SM_list_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, (haddr_t)extra); } else if(!HDmemcmp(sig, H5EA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug an extensible aray header. */ const H5EA_class_t *cls = get_H5EA_class(sig); HDassert(cls); /* Check for enough valid parameters */ if(extra == 0) { HDfprintf(stderr, "ERROR: Need object header address containing the layout message in order to dump header\n"); HDfprintf(stderr, "Extensible array header block usage:\n"); HDfprintf(stderr, "\th5debug <filename> <Extensible Array header address> <object header address>\n"); HDexit(4); } /* end if */ status = H5EA__hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra); } else if(!HDmemcmp(sig, H5EA_IBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug an extensible aray index block. */ const H5EA_class_t *cls = get_H5EA_class(sig); HDassert(cls); /* Check for enough valid parameters */ if(extra == 0 || extra2 == 0) { HDfprintf(stderr, "ERROR: Need extensible array header address and object header address containing the layout message in order to dump index block\n"); HDfprintf(stderr, "Extensible array index block usage:\n"); HDfprintf(stderr, "\th5debug <filename> <index block address> <array header address> <object header address\n"); HDexit(4); } /* end if */ status = H5EA__iblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, extra2); } else if(!HDmemcmp(sig, H5EA_SBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug an extensible aray super block. */ const H5EA_class_t *cls = get_H5EA_class(sig); HDassert(cls); /* Check for enough valid parameters */ if(extra == 0 || extra2 == 0 || extra3 == 0) { HDfprintf(stderr, "ERROR: Need extensible array header address, super block index and object header address containing the layout message in order to dump super block\n"); HDfprintf(stderr, "Extensible array super block usage:\n"); HDfprintf(stderr, "\th5debug <filename> <super block address> <array header address> <super block index> <object header address>\n"); HDexit(4); } /* end if */ status = H5EA__sblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, extra3); } else if(!HDmemcmp(sig, H5EA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug an extensible aray data block. */ const H5EA_class_t *cls = get_H5EA_class(sig); HDassert(cls); /* Check for enough valid parameters */ if(extra == 0 || extra2 == 0 || extra3 == 0) { HDfprintf(stderr, "ERROR: Need extensible array header address, # of elements in data block and object header address containing the layout message in order to dump data block\n"); HDfprintf(stderr, "Extensible array data block usage:\n"); HDfprintf(stderr, "\th5debug <filename> <data block address> <array header address> <# of elements in data block> <object header address\n"); HDexit(4); } /* end if */ status = H5EA__dblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, (size_t)extra2, extra3); } else if(!HDmemcmp(sig, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a fixed array header. */ const H5FA_class_t *cls = get_H5FA_class(sig); HDassert(cls); /* Check for enough valid parameters */ if(extra == 0) { HDfprintf(stderr, "ERROR: Need object header address containing the layout message in order to dump header\n"); HDfprintf(stderr, "Fixed array header block usage:\n"); HDfprintf(stderr, "\th5debug <filename> <Fixed Array header address> <object header address>\n"); HDexit(4); } /* end if */ status = H5FA__hdr_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra); } else if(!HDmemcmp(sig, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug a fixed array data block. */ const H5FA_class_t *cls = get_H5FA_class(sig); HDassert(cls); /* Check for enough valid parameters */ if(extra == 0 || extra2 == 0) { HDfprintf(stderr, "ERROR: Need fixed array header address and object header address containing the layout message in order to dump data block\n"); HDfprintf(stderr, "fixed array data block usage:\n"); HDfprintf(stderr, "\th5debug <filename> <data block address> <array header address> <object header address>\n"); HDexit(4); } /* end if */ status = H5FA__dblock_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL, cls, extra, extra2); } else if(!HDmemcmp(sig, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug v2 object header (which have signatures). */ status = H5O_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL); } else if(sig[0] == H5O_VERSION_1) { /* * This could be a v1 object header. Since they don't have a signature * it's a somewhat "ify" detection. */ status = H5O_debug(f, H5AC_ind_read_dxpl_id, addr, stdout, 0, VCOL); } else { /* * Got some other unrecognized signature. */ printf("%-*s ", VCOL, "Signature:"); for (u = 0; u < sizeof(sig); u++) { if (sig[u] > ' ' && sig[u] <= '~' && '\\' != sig[u]) HDputchar(sig[u]); else if ('\\' == sig[u]) { HDputchar('\\'); HDputchar('\\'); } else printf("\\%03o", sig[u]); } HDputchar('\n'); HDfprintf(stderr, "unknown signature\n"); HDexit(4); } /* end else */ /* Check for an error when dumping information */ if(status < 0) { HDfprintf(stderr, "An error occurred!\n"); H5Eprint2(H5E_DEFAULT, stderr); HDexit(5); } /* end if */ H5Pclose(fapl); H5Fclose(fid); H5Eset_auto2(H5E_DEFAULT, func, edata); return 0; } /* main() */
/*------------------------------------------------------------------------- * Function: H5B2_cache_hdr_load * * Purpose: Loads a B-tree header from the disk. * * Return: Success: Pointer to a new B-tree. * * Failure: NULL * * Programmer: Quincey Koziol * [email protected] * Feb 1 2005 * *------------------------------------------------------------------------- */ static H5B2_t * H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void UNUSED *udata) { const H5B2_class_t *type = (const H5B2_class_t *) _type; /* Type of B-tree */ unsigned depth; /* Depth of B-tree */ size_t node_size, rrec_size; /* Size info for B-tree */ uint8_t split_percent, merge_percent; /* Split & merge %s for B-tree */ H5B2_t *bt2 = NULL; /* B-tree info */ size_t size; /* Header size */ uint32_t stored_chksum; /* Stored metadata checksum value */ uint32_t computed_chksum; /* Computed metadata checksum value */ H5WB_t *wb = NULL; /* Wrapped buffer for header data */ uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */ uint8_t *hdr; /* Pointer to header buffer */ uint8_t *p; /* Pointer into raw data buffer */ H5B2_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5B2_cache_hdr_load, NULL) /* Check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(type); /* Allocate space for the B-tree data structure */ if(NULL == (bt2 = H5FL_MALLOC(H5B2_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t)); /* Wrap the local buffer for serialized header info */ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf)))) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't wrap buffer") /* Compute the size of the serialized B-tree header on disk */ size = H5B2_HEADER_SIZE(f); /* Get a pointer to a buffer that's large enough for header */ if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, size))) HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't get actual buffer") /* Read header from disk */ if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0) HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree header") /* Get temporary pointer to serialized header */ p = hdr; /* Magic number */ if(HDmemcmp(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree header signature") p += H5_SIZEOF_MAGIC; /* Version */ if(*p++ != H5B2_HDR_VERSION) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree header version") /* B-tree type */ if(*p++ != (uint8_t)type->id) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "incorrect B-tree type") /* Node size (in bytes) */ UINT32DECODE(p, node_size); /* Raw key size (in bytes) */ UINT16DECODE(p, rrec_size); /* Depth of tree */ UINT16DECODE(p, depth); /* Split & merge %s */ split_percent = *p++; merge_percent = *p++; /* Root node pointer */ H5F_addr_decode(f, (const uint8_t **)&p, &(bt2->root.addr)); UINT16DECODE(p, bt2->root.node_nrec); H5F_DECODE_LENGTH(f, p, bt2->root.all_nrec); /* Metadata checksum */ UINT32DECODE(p, stored_chksum); /* Sanity check */ HDassert((size_t)(p - hdr) == size); /* Compute checksum on entire header */ computed_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0); /* Verify checksum */ if(stored_chksum != computed_chksum) HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 B-tree header") /* Initialize shared B-tree info */ if(H5B2_shared_init(f, bt2, type, depth, node_size, rrec_size, split_percent, merge_percent) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't create shared B-tree info") /* Set return value */ ret_value = bt2; done: /* Release resources */ if(wb && H5WB_unwrap(wb) < 0) HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer") if(!ret_value && bt2) (void)H5B2_cache_hdr_dest(f, bt2); FUNC_LEAVE_NOAPI(ret_value) } /* end H5B2_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */
/*------------------------------------------------------------------------- * Function: test_1 * * Purpose: Writes a sequence of objects to the global heap where each * object is larger than the one before. * * Return: Success: 0 * * Failure: number of errors * * Programmer: Robb Matzke * Tuesday, March 31, 1998 * * Modifications: * *------------------------------------------------------------------------- */ static int test_1 (hid_t fapl) { hid_t file = -1; H5F_t *f = NULL; H5HG_t obj[1024]; uint8_t out[1024]; uint8_t in[1024]; int i; size_t size; herr_t status; int nerrors = 0; char filename[1024]; TESTING("monotonically increasing lengths"); /* Open a clean file */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) goto error; if(NULL == (f = (H5F_t *)H5I_object(file))) { H5_FAILED(); puts(" Unable to create file"); goto error; } /* * Write the objects, monotonically increasing in length. Since this is * a clean file, the addresses allocated for the collections should also * be monotonically increasing. */ for(i = 0; i < 1024; i++) { size = i + 1; HDmemset(out, 'A' + i % 26, size); H5Eclear2(H5E_DEFAULT); status = H5HG_insert(f, H5P_DATASET_XFER_DEFAULT, size, out, obj + i); if(status < 0) { H5_FAILED(); puts(" Unable to insert object into global heap"); nerrors++; } else if(i && H5F_addr_gt(obj[i - 1].addr, obj[i].addr)) { H5_FAILED(); puts(" Collection addresses are not monotonically increasing"); nerrors++; } } /* * Now try to read each object back. */ for(i = 0; i < 1024; i++) { size = i + 1; HDmemset(out, 'A' + i % 26, size); H5Eclear2(H5E_DEFAULT); if(NULL == H5HG_read(f, H5P_DATASET_XFER_DEFAULT, obj + i, in, NULL)) { H5_FAILED(); puts(" Unable to read object"); nerrors++; } else if(HDmemcmp(in, out, size)) { H5_FAILED(); puts(" Value read doesn't match value written"); nerrors++; } } if(H5Fclose(file) < 0) goto error; if(nerrors) goto error; PASSED(); return 0; error: H5E_BEGIN_TRY { H5Fclose(file); } H5E_END_TRY; return MAX(1, nerrors); }