/*------------------------------------------------------------------------- * Function: H5Iget_name * * Purpose: Gets a name of an object from its ID. * * Return: Success: The length of name. * * Failure: -1 * * Programmer: Pedro Vicente, [email protected] * * Date: July 26, 2002 * * Comments: Public function * If `name' is non-NULL then write up to `size' bytes into that * buffer and always return the length of the entry name. * Otherwise `size' is ignored and the function does not store the name, * just returning the number of characters required to store the name. * If an error occurs then the buffer pointed to by `name' (NULL or non-NULL) * is unchanged and the function returns a negative value. * If a zero is returned for the name's length, then there is no name * associated with the ID. * * Modifications: * *------------------------------------------------------------------------- */ ssize_t H5Iget_name(hid_t id, char *name/*out*/, size_t size) { H5G_entry_t *ent; /*symbol table entry */ size_t len=0; ssize_t ret_value; FUNC_ENTER_API (H5Iget_name, FAIL); H5TRACE3("Zs","ixz",id,name,size); /* get symbol table entry */ if(NULL!=(ent = H5G_loc(id))) { if (ent->user_path_r != NULL && ent->user_path_hidden==0) { len = H5RS_len(ent->user_path_r); if(name) { HDstrncpy(name, H5RS_get_str(ent->user_path_r), MIN(len+1,size)); if(len >= size) name[size-1]='\0'; } /* end if */ } /* end if */ } /* end if */ /* Set return value */ ret_value=(ssize_t)len; done: FUNC_LEAVE_API(ret_value); }
/*-------------------------------------------------------------------------- NAME DFPIopen -- open/reopen file for palette interface USAGE int32 DFPIopen(filename,acc_mode) char *filename; IN: name of HDF file intn acc_mode; IN: type of access to open file with RETURNS HDF file handle on success, FAIL on failure. DESCRIPTION Open/reopen a file for the DFP interface to work with. GLOBAL VARIABLES Refset, Readref, Lastfile COMMENTS, BUGS, ASSUMPTIONS This is a hook for someday providing more efficient ways to reopen a file, to avoid re-reading all the headers EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ PRIVATE int32 DFPIopen(const char *filename, intn acc_mode) { CONSTR(FUNC, "DFPIopen"); int32 file_id; int32 ret_value = SUCCEED; /* use reopen if same file as last time - more efficient */ if (HDstrncmp(Lastfile, filename, DF_MAXFNLEN) || (acc_mode == DFACC_CREATE)) { /* treat create as different file */ if ((file_id = Hopen(filename, acc_mode, 0)) == FAIL) HGOTO_ERROR(DFE_BADOPEN, FAIL); Refset = 0; /* no ref to get set for this file */ Readref = 0; } /* end if */ else if ((file_id = Hopen(filename, acc_mode, 0)) == FAIL) HGOTO_ERROR(DFE_BADOPEN, FAIL); /* remember filename, so reopen may be used next time if same file */ HDstrncpy(Lastfile, filename, DF_MAXFNLEN); ret_value = (file_id); done: if(ret_value == FAIL) { /* Error condition cleanup */ } /* end if */ /* Normal function cleanup */ return ret_value; } /* end DFPIopen() */
herr_t H5AwriteVL_str (JNIEnv *env, hid_t aid, hid_t tid, jobjectArray buf) { herr_t status = -1; char **wdata; jsize size; jint i; size = ENVPTR->GetArrayLength(ENVPAR (jarray) buf); wdata = (char**)HDcalloc((size_t)size + 1, sizeof(char*)); if (!wdata) { h5JNIFatalError(env, "H5AwriteVL_str: cannot allocate buffer"); } /* end if */ else { HDmemset(wdata, 0, (size_t)size * sizeof(char*)); for (i = 0; i < size; ++i) { jstring obj = (jstring) ENVPTR->GetObjectArrayElement(ENVPAR (jobjectArray) buf, i); if (obj != 0) { jsize length = ENVPTR->GetStringUTFLength(ENVPAR obj); const char *utf8 = ENVPTR->GetStringUTFChars(ENVPAR obj, 0); if (utf8) { wdata[i] = (char*)HDmalloc((size_t)length + 1); if (wdata[i]) { HDmemset(wdata[i], 0, ((size_t)length + 1)); HDstrncpy(wdata[i], utf8, (size_t)length); } /* end if */ } /* end if */ ENVPTR->ReleaseStringUTFChars(ENVPAR obj, utf8); ENVPTR->DeleteLocalRef(ENVPAR obj); } /* end if */ } /* end for (i = 0; i < size; ++i) */ status = H5Awrite((hid_t)aid, (hid_t)tid, wdata); for (i = 0; i < size; i++) { if(wdata[i]) { HDfree(wdata[i]); } /* end if */ } /* end for */ HDfree(wdata); if (status < 0) h5libraryError(env); } /* end else */ return (jint)status; }
/*------------------------------------------------------------------------- * Function: H5O_pline_decode * * Purpose: Decodes a filter pipeline message. * * Return: Success: Ptr to the native message. * Failure: NULL * * Programmer: Robb Matzke * Wednesday, April 15, 1998 * *------------------------------------------------------------------------- */ static void * H5O_pline_decode(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, H5O_t H5_ATTR_UNUSED *open_oh, unsigned H5_ATTR_UNUSED mesg_flags, unsigned H5_ATTR_UNUSED *ioflags, const uint8_t *p) { H5O_pline_t *pline = NULL; /* Pipeline message */ H5Z_filter_info_t *filter; /* Filter to decode */ size_t name_length; /* Length of filter name */ size_t i; /* Local index variable */ void *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* check args */ HDassert(p); /* Allocate space for I/O pipeline message */ if(NULL == (pline = H5FL_CALLOC(H5O_pline_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Version */ pline->version = *p++; if(pline->version < H5O_PLINE_VERSION_1 || pline->version > H5O_PLINE_VERSION_LATEST) HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "bad version number for filter pipeline message") /* Number of filters */ pline->nused = *p++; if(pline->nused > H5Z_MAX_NFILTERS) HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter pipeline message has too many filters") /* Reserved */ if(pline->version == H5O_PLINE_VERSION_1) p += 6; /* Allocate array for filters */ pline->nalloc = pline->nused; if(NULL == (pline->filter = (H5Z_filter_info_t *)H5MM_calloc(pline->nalloc * sizeof(pline->filter[0])))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Decode filters */ for(i = 0, filter = &pline->filter[0]; i < pline->nused; i++, filter++) { /* Filter ID */ UINT16DECODE(p, filter->id); /* Length of filter name */ if(pline->version > H5O_PLINE_VERSION_1 && filter->id < H5Z_FILTER_RESERVED) name_length = 0; else { UINT16DECODE(p, name_length); if(pline->version == H5O_PLINE_VERSION_1 && name_length % 8) HGOTO_ERROR(H5E_PLINE, H5E_CANTLOAD, NULL, "filter name length is not a multiple of eight") } /* end if */ /* Filter flags */ UINT16DECODE(p, filter->flags); /* Number of filter parameters ("client data elements") */ UINT16DECODE(p, filter->cd_nelmts); /* Filter name, if there is one */ if(name_length) { size_t actual_name_length; /* Actual length of name */ /* Determine actual name length (without padding, but with null terminator) */ actual_name_length = HDstrlen((const char *)p) + 1; HDassert(actual_name_length <= name_length); /* Allocate space for the filter name, or use the internal buffer */ if(actual_name_length > H5Z_COMMON_NAME_LEN) { filter->name = (char *)H5MM_malloc(actual_name_length); if(NULL == filter->name) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for filter name") } /* end if */ else filter->name = filter->_name; HDstrncpy(filter->name, (const char *)p, actual_name_length); p += name_length; } /* end if */
/* * Function: h5_set_info_object * Purpose: Process environment variables setting to set up MPI Info * object. * Return: 0 if all is fine; otherwise non-zero. * Programmer: Albert Cheng, 2002/05/21. * Modifications: * Bill Wendling, 2002/05/31 * Modified so that the HDF5_MPI_INFO environment variable can * be a semicolon separated list of "key=value" pairings. Most * of the code is to remove any whitespaces which might be * surrounding the "key=value" pairs. */ int h5_set_info_object(void) { char *envp; /* environment pointer */ int ret_value=0; /* handle any MPI INFO hints via $HDF5_MPI_INFO */ if ((envp = getenv("HDF5_MPI_INFO")) != NULL){ char *next, *valp; valp = envp = next = HDstrdup(envp); if (!valp) return 0; /* create an INFO object if not created yet */ if (h5_io_info_g == MPI_INFO_NULL) MPI_Info_create(&h5_io_info_g); do { size_t len; char *key_val, *endp, *namep; if (*valp == ';') valp++; /* copy key/value pair into temporary buffer */ len = strcspn(valp, ";"); next = &valp[len]; key_val = (char *)HDcalloc(1, len + 1); /* increment the next pointer past the terminating semicolon */ if (*next == ';') ++next; namep = HDstrncpy(key_val, valp, len); /* pass up any beginning whitespaces */ while (*namep && (*namep == ' ' || *namep == '\t')) namep++; if (!*namep) continue; /* was all white space, so move to next k/v pair */ /* eat up any ending white spaces */ endp = &namep[HDstrlen(namep) - 1]; while (endp && (*endp == ' ' || *endp == '\t')) *endp-- = '\0'; /* find the '=' */ valp = HDstrchr(namep, '='); if (valp != NULL) { /* it's a valid key/value pairing */ char *tmp_val = valp + 1; /* change '=' to \0, move valp down one */ *valp-- = '\0'; /* eat up ending whitespace on the "key" part */ while (*valp == ' ' || *valp == '\t') *valp-- = '\0'; valp = tmp_val; /* eat up beginning whitespace on the "value" part */ while (*valp == ' ' || *valp == '\t') *valp++ = '\0'; /* actually set the darned thing */ if (MPI_SUCCESS != MPI_Info_set(h5_io_info_g, namep, valp)) { printf("MPI_Info_set failed\n"); ret_value = -1; } } valp = next; HDfree(key_val); } while (next && *next); HDfree(envp); } return ret_value; }
/*------------------------------------------------------------------------- * Function: h5_fileaccess * * Purpose: Returns a file access template which is the default template * but with a file driver set according to the constant or * environment variable HDF5_DRIVER * * Return: Success: A file access property list * * Failure: -1 * * Programmer: Robb Matzke * Thursday, November 19, 1998 * * Modifications: * *------------------------------------------------------------------------- */ hid_t h5_fileaccess(void) { const char *val = NULL; const char *name; char s[1024]; hid_t fapl = -1; /* First use the environment variable, then the constant */ val = HDgetenv("HDF5_DRIVER"); #ifdef HDF5_DRIVER if (!val) val = HDF5_DRIVER; #endif if ((fapl=H5Pcreate(H5P_FILE_ACCESS))<0) return -1; if (!val || !*val) return fapl; /*use default*/ HDstrncpy(s, val, sizeof s); s[sizeof(s)-1] = '\0'; if (NULL==(name=HDstrtok(s, " \t\n\r"))) return fapl; if (!HDstrcmp(name, "sec2")) { /* Unix read() and write() system calls */ if (H5Pset_fapl_sec2(fapl)<0) return -1; } else if (!HDstrcmp(name, "stdio")) { /* Standard C fread() and fwrite() system calls */ if (H5Pset_fapl_stdio(fapl)<0) return -1; } else if (!HDstrcmp(name, "core")) { /* In-memory driver settings (backing store on, 1 MB increment) */ if (H5Pset_fapl_core(fapl, (size_t)1, TRUE)<0) return -1; } else if (!HDstrcmp(name, "core_paged")) { /* In-memory driver with write tracking and paging on */ if (H5Pset_fapl_core(fapl, (size_t)1, TRUE)<0) return -1; if (H5Pset_core_write_tracking(fapl, TRUE, (size_t)4096)<0) return -1; } else if (!HDstrcmp(name, "split")) { /* Split meta data and raw data each using default driver */ if (H5Pset_fapl_split(fapl, "-m.h5", H5P_DEFAULT, "-r.h5", H5P_DEFAULT)<0) return -1; } else if (!HDstrcmp(name, "multi")) { /* Multi-file driver, general case of the split driver */ H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; hid_t memb_fapl[H5FD_MEM_NTYPES]; const char *memb_name[H5FD_MEM_NTYPES]; char sv[H5FD_MEM_NTYPES][1024]; haddr_t memb_addr[H5FD_MEM_NTYPES]; H5FD_mem_t mt; HDmemset(memb_map, 0, sizeof memb_map); HDmemset(memb_fapl, 0, sizeof memb_fapl); HDmemset(memb_name, 0, sizeof memb_name); HDmemset(memb_addr, 0, sizeof memb_addr); HDassert(HDstrlen(multi_letters)==H5FD_MEM_NTYPES); for(mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, mt)) { memb_fapl[mt] = H5P_DEFAULT; sprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]); memb_name[mt] = sv[mt]; memb_addr[mt] = (haddr_t)MAX(mt - 1, 0) * (HADDR_MAX / 10); } /* end for */ if (H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, memb_addr, FALSE)<0) { return -1; } } else if (!HDstrcmp(name, "family")) { hsize_t fam_size = 100*1024*1024; /*100 MB*/ /* Family of files, each 1MB and using the default driver */ if ((val=HDstrtok(NULL, " \t\n\r"))) fam_size = (hsize_t)(HDstrtod(val, NULL) * 1024*1024); if (H5Pset_fapl_family(fapl, fam_size, H5P_DEFAULT)<0) return -1; } else if (!HDstrcmp(name, "log")) { unsigned log_flags = H5FD_LOG_LOC_IO | H5FD_LOG_ALLOC; /* Log file access */ if ((val = HDstrtok(NULL, " \t\n\r"))) log_flags = (unsigned)HDstrtol(val, NULL, 0); if (H5Pset_fapl_log(fapl, NULL, log_flags, (size_t)0) < 0) return -1; } else if (!HDstrcmp(name, "direct")) { #ifdef H5_HAVE_DIRECT /* Linux direct read() and write() system calls. Set memory boundary, file block size, * and copy buffer size to the default values. */ if (H5Pset_fapl_direct(fapl, 1024, 4096, 8*4096)<0) return -1; #endif } else if(!HDstrcmp(name, "latest")) { /* use the latest format */ if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) return -1; } else { /* Unknown driver */ return -1; } return fapl; }
/*------------------------------------------------------------------------- * Function: h5_fixname * * Purpose: Create a file name from a file base name like `test' and * return it through the FULLNAME (at most SIZE characters * counting the null terminator). The full name is created by * prepending the contents of HDF5_PREFIX (separated from the * base name by a slash) and appending a file extension based on * the driver supplied, resulting in something like * `ufs:/u/matzke/test.h5'. * * Return: Success: The FULLNAME pointer. * * Failure: NULL if BASENAME or FULLNAME is the null * pointer or if FULLNAME isn't large enough for * the result. * * Programmer: Robb Matzke * Thursday, November 19, 1998 * *------------------------------------------------------------------------- */ char * h5_fixname(const char *base_name, hid_t fapl, char *fullname, size_t size) { const char *prefix = NULL; const char *suffix = ".h5"; /* suffix has default */ char *ptr, last = '\0'; size_t i, j; hid_t driver = -1; int isppdriver = 0; /* if the driver is MPI parallel */ if (!base_name || !fullname || size < 1) return NULL; HDmemset(fullname, 0, size); /* figure out the suffix */ if(H5P_DEFAULT != fapl) { if((driver = H5Pget_driver(fapl)) < 0) return NULL; if(H5FD_FAMILY == driver) suffix = "%05d.h5"; else if (H5FD_MULTI == driver) suffix = NULL; } /* Must first check fapl is not H5P_DEFAULT (-1) because H5FD_XXX * could be of value -1 if it is not defined. */ isppdriver = H5P_DEFAULT != fapl && (H5FD_MPIO==driver); /* Check HDF5_NOCLEANUP environment setting. * (The #ifdef is needed to prevent compile failure in case MPI is not * configured.) */ if(isppdriver) { #ifdef H5_HAVE_PARALLEL if(getenv_all(MPI_COMM_WORLD, 0, "HDF5_NOCLEANUP")) SetTestNoCleanup(); #endif /* H5_HAVE_PARALLEL */ } else { if(HDgetenv("HDF5_NOCLEANUP")) SetTestNoCleanup(); } /* Check what prefix to use for test files. Process HDF5_PARAPREFIX and * HDF5_PREFIX. * Use different ones depending on parallel or serial driver used. * (The #ifdef is needed to prevent compile failure in case MPI is not * configured.) */ if(isppdriver) { #ifdef H5_HAVE_PARALLEL /* * For parallel: * First use command line option, then the environment * variable, then try the constant */ static int explained = 0; prefix = (paraprefix ? paraprefix : getenv_all(MPI_COMM_WORLD, 0, "HDF5_PARAPREFIX")); if (!prefix && !explained) { /* print hint by process 0 once. */ int mpi_rank; MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); if (mpi_rank == 0) printf("*** Hint ***\n" "You can use environment variable HDF5_PARAPREFIX to " "run parallel test files in a\n" "different directory or to add file type prefix. E.g.,\n" " HDF5_PARAPREFIX=pfs:/PFS/user/me\n" " export HDF5_PARAPREFIX\n" "*** End of Hint ***\n"); explained = TRUE; #ifdef HDF5_PARAPREFIX prefix = HDF5_PARAPREFIX; #endif /* HDF5_PARAPREFIX */ } #endif /* H5_HAVE_PARALLEL */ } else { /* * For serial: * First use the environment variable, then try the constant */ prefix = HDgetenv("HDF5_PREFIX"); #ifdef HDF5_PREFIX if (!prefix) prefix = HDF5_PREFIX; #endif /* HDF5_PREFIX */ } /* Prepend the prefix value to the base name */ if (prefix && *prefix) { if (isppdriver) { /* This is a parallel system */ char *subdir; if (!HDstrcmp(prefix, HDF5_PARAPREFIX)) { /* * If the prefix specifies the HDF5_PARAPREFIX directory, then * default to using the "/tmp/$USER" or "/tmp/$LOGIN" * directory instead. */ char *user, *login; user = HDgetenv("USER"); login = HDgetenv("LOGIN"); subdir = (user ? user : login); if (subdir) { for (i = 0; i < size && prefix[i]; i++) fullname[i] = prefix[i]; fullname[i++] = '/'; for (j = 0; i < size && subdir[j]; ++i, ++j) fullname[i] = subdir[j]; } } if (!fullname[0]) { /* We didn't append the prefix yet */ HDstrncpy(fullname, prefix, size); fullname[size -1] = '\0'; } if (HDstrlen(fullname) + HDstrlen(base_name) + 1 < size) { /* * Append the base_name with a slash first. Multiple * slashes are handled below. */ h5_stat_t buf; if (HDstat(fullname, &buf) < 0) /* The directory doesn't exist just yet */ if (HDmkdir(fullname, (mode_t)0755) < 0 && errno != EEXIST) /* * We couldn't make the "/tmp/${USER,LOGIN}" * subdirectory. Default to PREFIX's original * prefix value. */ HDstrcpy(fullname, prefix); HDstrcat(fullname, "/"); HDstrcat(fullname, base_name); } else { /* Buffer is too small */ return NULL; } } else { if (HDsnprintf(fullname, size, "%s/%s", prefix, base_name) == (int)size) /* Buffer is too small */ return NULL; } } else if (HDstrlen(base_name) >= size) { /* Buffer is too small */ return NULL; } else { HDstrcpy(fullname, base_name); } /* Append a suffix */ if (suffix) { if (HDstrlen(fullname) + HDstrlen(suffix) >= size) return NULL; HDstrcat(fullname, suffix); } /* Remove any double slashes in the filename */ for (ptr = fullname, i = j = 0; ptr && i < size; i++, ptr++) { if (*ptr != '/' || last != '/') fullname[j++] = *ptr; last = *ptr; } return fullname; }
/* * 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: print_header * * Purpose: Prints the header for the generated file. * * Return: void *------------------------------------------------------------------------- */ static void print_header(void) { time_t now = HDtime(NULL); struct tm *tm = HDlocaltime(&now); char real_name[30]; char host_name[256]; int i; const char *s; #ifdef H5_HAVE_GETPWUID struct passwd *pwd = NULL; #else int pwd = 1; #endif static const char *month_name[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; static const char *purpose = "\ This machine-generated source code contains\n\ information about the library build configuration\n"; /* * The real name is the first item from the passwd gecos field. */ #ifdef H5_HAVE_GETPWUID { size_t n; char *comma; if((pwd = HDgetpwuid(HDgetuid()))) { if((comma = HDstrchr(pwd->pw_gecos, ','))) { n = MIN(sizeof(real_name) - 1, (unsigned)(comma - pwd->pw_gecos)); HDstrncpy(real_name, pwd->pw_gecos, n); real_name[n] = '\0'; } /* end if */ else { HDstrncpy(real_name, pwd->pw_gecos, sizeof(real_name)); real_name[sizeof(real_name) - 1] = '\0'; } /* end else */ } /* end if */ else real_name[0] = '\0'; } #else real_name[0] = '\0'; #endif /* * The FQDM of this host or the empty string. */ #ifdef H5_HAVE_GETHOSTNAME if(HDgethostname(host_name, sizeof(host_name)) < 0) host_name[0] = '\0'; #else host_name[0] = '\0'; #endif /* * The file header: warning, copyright notice, build information. */ fprintf(rawoutstream, "/* Generated automatically by H5make_libsettings -- do not edit */\n\n\n"); HDfputs(FileHeader, rawoutstream); /*the copyright notice--see top of this file */ fprintf(rawoutstream, " *\n * Created:\t\t%s %2d, %4d\n", month_name[tm->tm_mon], tm->tm_mday, 1900 + tm->tm_year); if(pwd || real_name[0] || host_name[0]) { fprintf(rawoutstream, " *\t\t\t"); if(real_name[0]) fprintf(rawoutstream, "%s <", real_name); #ifdef H5_HAVE_GETPWUID if(pwd) HDfputs(pwd->pw_name, rawoutstream); #endif if(host_name[0]) fprintf(rawoutstream, "@%s", host_name); if(real_name[0]) fprintf(rawoutstream, ">"); HDfputc('\n', rawoutstream); } /* end if */ fprintf(rawoutstream, " *\n * Purpose:\t\t"); for(s = purpose; *s; s++) { HDfputc(*s, rawoutstream); if('\n' == *s && s[1]) fprintf(rawoutstream, " *\t\t\t"); } /* end for */ fprintf(rawoutstream, " *\n * Modifications:\n *\n"); fprintf(rawoutstream, " *\tDO NOT MAKE MODIFICATIONS TO THIS FILE!\n"); fprintf(rawoutstream, " *\tIt was generated by code in `H5make_libsettings.c'.\n"); fprintf(rawoutstream, " *\n *"); for(i = 0; i < 73; i++) HDfputc('-', rawoutstream); fprintf(rawoutstream, "\n */\n\n"); }
/*------------------------------------------------------------------------- * Function: H5F_sblock_load * * Purpose: Loads the superblock from the file, and deserializes * its information into the H5F_super_t structure. * * Return: Success: SUCCEED * Failure: NULL * * Programmer: Mike McGreevy * [email protected] * April 8, 2009 * *------------------------------------------------------------------------- */ static H5F_super_t * H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata) { H5F_super_t *sblock = NULL; /* File's superblock */ haddr_t base_addr = HADDR_UNDEF; /* Base address of file */ uint8_t sbuf[H5F_MAX_SUPERBLOCK_SIZE]; /* Buffer for superblock */ H5P_genplist_t *dxpl; /* DXPL object */ H5P_genplist_t *c_plist; /* File creation property list */ H5F_file_t *shared; /* shared part of `file' */ H5FD_t *lf; /* file driver part of `shared' */ haddr_t stored_eoa; /*relative end-of-addr in file */ haddr_t eof; /*end of file address */ uint8_t sizeof_addr; /* Size of offsets in the file (in bytes) */ uint8_t sizeof_size; /* Size of lengths in the file (in bytes) */ const size_t fixed_size = H5F_SUPERBLOCK_FIXED_SIZE; /*fixed sizeof superblock */ size_t variable_size; /*variable sizeof superblock */ uint8_t *p; /* Temporary pointer into encoding buffer */ unsigned super_vers; /* Superblock version */ hbool_t *dirtied = (hbool_t *)_udata; /* Set up dirtied out value */ H5F_super_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* check arguments */ HDassert(f); HDassert(H5F_addr_eq(addr, 0)); HDassert(dirtied); /* Short cuts */ shared = f->shared; lf = shared->lf; /* Get the shared file creation property list */ if(NULL == (c_plist = (H5P_genplist_t *)H5I_object(shared->fcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get property list") /* Get the base address for the file in the VFD */ if(HADDR_UNDEF == (base_addr = H5FD_get_base_addr(lf))) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "failed to get base address for file driver") /* Allocate space for the superblock */ if(NULL == (sblock = H5FL_CALLOC(H5F_super_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Get the DXPL plist object for DXPL ID */ if(NULL == (dxpl = (H5P_genplist_t *)H5I_object(dxpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get property list") /* Read fixed-size portion of the superblock */ p = sbuf; H5_CHECK_OVERFLOW(fixed_size, size_t, haddr_t); if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)fixed_size) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed") if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, (haddr_t)0, fixed_size, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") /* Skip over signature (already checked when locating the superblock) */ p += H5F_SIGNATURE_LEN; /* Superblock version */ super_vers = *p++; if(super_vers > HDF5_SUPERBLOCK_VERSION_LATEST) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad superblock version number") if(H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set superblock version") /* Record the superblock version */ sblock->super_vers = super_vers; /* Sanity check */ HDassert(((size_t)(p - sbuf)) == fixed_size); /* Determine the size of the variable-length part of the superblock */ variable_size = (size_t)H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, f); HDassert(variable_size > 0); HDassert(fixed_size + variable_size <= sizeof(sbuf)); /* Read in variable-sized portion of superblock */ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)(fixed_size + variable_size)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed") if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, (haddr_t)fixed_size, variable_size, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read superblock") /* Check for older version of superblock format */ if(super_vers < HDF5_SUPERBLOCK_VERSION_2) { uint32_t status_flags; /* File status flags */ unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree internal node 'K' values */ unsigned sym_leaf_k; /* Symbol table leaf node's 'K' value */ /* Freespace version (hard-wired) */ if(HDF5_FREESPACE_VERSION != *p++) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad free space version number") /* Root group version number (hard-wired) */ if(HDF5_OBJECTDIR_VERSION != *p++) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad object directory version number") /* Skip over reserved byte */ p++; /* Shared header version number (hard-wired) */ if(HDF5_SHAREDHEADER_VERSION != *p++) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad shared-header format version number") /* Size of file addresses */ sizeof_addr = *p++; if(sizeof_addr != 2 && sizeof_addr != 4 && sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address") if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number in an address") shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */ /* Size of file sizes */ sizeof_size = *p++; if(sizeof_size != 2 && sizeof_size != 4 && sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number for object size") if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number for object size") shared->sizeof_size = sizeof_size; /* Keep a local copy also */ /* Skip over reserved byte */ p++; /* Various B-tree sizes */ UINT16DECODE(p, sym_leaf_k); if(sym_leaf_k == 0) HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad symbol table leaf node 1/2 rank") if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for symbol table leaf nodes") sblock->sym_leaf_k = sym_leaf_k; /* Keep a local copy also */ /* Need 'get' call to set other array values */ if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get rank for btree internal nodes") UINT16DECODE(p, btree_k[H5B_SNODE_ID]); if(btree_k[H5B_SNODE_ID] == 0) HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad 1/2 rank for btree internal nodes") /* * Delay setting the value in the property list until we've checked * for the indexed storage B-tree internal 'K' value later. */ /* File status flags (not really used yet) */ UINT32DECODE(p, status_flags); HDassert(status_flags <= 255); sblock->status_flags = (uint8_t)status_flags; if(sblock->status_flags & ~H5F_SUPER_ALL_FLAGS) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad flag value for superblock") /* * If the superblock version # is greater than 0, read in the indexed * storage B-tree internal 'K' value */ if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) { UINT16DECODE(p, btree_k[H5B_CHUNK_ID]); /* Reserved bytes are present only in version 1 */ if(super_vers == HDF5_SUPERBLOCK_VERSION_1) p += 2; /* reserved */ } /* end if */ else btree_k[H5B_CHUNK_ID] = HDF5_BTREE_CHUNK_IK_DEF; /* Set the B-tree internal node values, etc */ if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set rank for btree internal nodes") HDmemcpy(sblock->btree_k, btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID); /* Keep a local copy also */ /* Remainder of "variable-sized" portion of superblock */ H5F_addr_decode(f, (const uint8_t **)&p, &sblock->base_addr/*out*/); H5F_addr_decode(f, (const uint8_t **)&p, &sblock->ext_addr/*out*/); H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/); H5F_addr_decode(f, (const uint8_t **)&p, &sblock->driver_addr/*out*/); /* Allocate space for the root group symbol table entry */ HDassert(!sblock->root_ent); if(NULL == (sblock->root_ent = (H5G_entry_t *)H5MM_calloc(sizeof(H5G_entry_t)))) HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate space for root group symbol table entry") /* decode the root group symbol table entry */ if(H5G_ent_decode(f, (const uint8_t **)&p, sblock->root_ent) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode root group symbol table entry") /* Set the root group address to the correct value */ sblock->root_addr = sblock->root_ent->header; /* * Check if superblock address is different from base address and * adjust base address and "end of address" address if so. */ if(!H5F_addr_eq(base_addr, sblock->base_addr)) { /* Check if the superblock moved earlier in the file */ if(H5F_addr_lt(base_addr, sblock->base_addr)) stored_eoa -= (sblock->base_addr - base_addr); else /* The superblock moved later in the file */ stored_eoa += (base_addr - sblock->base_addr); /* Adjust base address for offsets of the HDF5 data in the file */ sblock->base_addr = base_addr; /* Set the base address for the file in the VFD now */ if(H5FD_set_base_addr(lf, sblock->base_addr) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "failed to set base address for file driver") /* Indicate that the superblock should be marked dirty */ *dirtied = TRUE; } /* end if */ /* This step is for h5repart tool only. If user wants to change file driver * from family to sec2 while using h5repart, set the driver address to * undefined to let the library ignore the family driver information saved * in the superblock. */ if(H5F_HAS_FEATURE(f, H5FD_FEAT_IGNORE_DRVRINFO)) { /* Eliminate the driver info */ sblock->driver_addr = HADDR_UNDEF; /* Indicate that the superblock should be marked dirty */ *dirtied = TRUE; } /* end if */ /* Decode the optional driver information block */ if(H5F_addr_defined(sblock->driver_addr)) { uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Buffer for driver info block */ char drv_name[9]; /* Name of driver */ unsigned drv_vers; /* Version of driver info block */ size_t drv_variable_size; /* Size of variable-length portion of driver info block, in bytes */ /* Read in fixed-sized portion of driver info block */ p = dbuf; if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed") if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, sblock->driver_addr, (size_t)H5F_DRVINFOBLOCK_HDR_SIZE, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read driver information block") /* Version number */ drv_vers = *p++; if(drv_vers != HDF5_DRIVERINFO_VERSION_0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad driver information block version number") p += 3; /* reserved bytes */ /* Driver info size */ UINT32DECODE(p, drv_variable_size); /* Sanity check */ HDassert(H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size <= sizeof(dbuf)); /* Driver name and/or version */ HDstrncpy(drv_name, (const char *)p, (size_t)8); drv_name[8] = '\0'; p += 8; /* advance past name/version */ /* Check if driver matches driver information saved. Unfortunately, we can't push this * function to each specific driver because we're checking if the driver is correct. */ if(!HDstrncmp(drv_name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family")) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "family driver should be used") if(!HDstrncmp(drv_name, "NCSAmult", (size_t)8) && HDstrcmp(lf->cls->name, "multi")) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "multi driver should be used") /* Read in variable-sized portion of driver info block */ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed") if(H5FD_read(lf, dxpl, H5FD_MEM_SUPER, sblock->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE, drv_variable_size, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read file driver information") /* Decode driver information */ if(H5FD_sb_decode(lf, drv_name, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to decode driver information") } /* end if */
int main (int argc, const char *argv[]) { hid_t fid_src = -1; hid_t fid_dst = -1; unsigned flag = 0; unsigned verbose = 0; unsigned parents = 0; hid_t ocpl_id = (-1); /* Object copy property list */ hid_t lcpl_id = (-1); /* Link creation property list */ int opt; int li_ret; h5tool_link_info_t linkinfo; h5tools_setprogname(PROGRAMNAME); h5tools_setstatus(EXIT_SUCCESS); /* initialize h5tools lib */ h5tools_init(); /* init linkinfo struct */ HDmemset(&linkinfo, 0, sizeof(h5tool_link_info_t)); /* Check for no command line parameters */ if(argc == 1) { usage(); leave(EXIT_FAILURE); } /* end if */ /* parse command line options */ while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) { switch ((char)opt) { case 'd': oname_dst = HDstrdup(opt_arg); break; case 'f': /* validate flag */ if (parse_flag(opt_arg,&flag)<0) { usage(); leave(EXIT_FAILURE); } str_flag = HDstrdup(opt_arg); break; case 'h': usage(); leave(EXIT_SUCCESS); break; case 'i': fname_src = HDstrdup(opt_arg); break; case 'o': fname_dst = HDstrdup(opt_arg); break; case 'p': parents = 1; break; case 's': oname_src = HDstrdup(opt_arg); break; case 'V': print_version(h5tools_getprogname()); leave(EXIT_SUCCESS); break; case 'v': verbose = 1; break; default: usage(); leave(EXIT_FAILURE); } } /* end of while */ /*------------------------------------------------------------------------- * check for missing file/object names *-------------------------------------------------------------------------*/ if (fname_src==NULL) { error_msg("Input file name missing\n"); usage(); leave(EXIT_FAILURE); } if (fname_dst==NULL) { error_msg("Output file name missing\n"); usage(); leave(EXIT_FAILURE); } if (oname_src==NULL) { error_msg("Source object name missing\n"); usage(); leave(EXIT_FAILURE); } if (oname_dst==NULL) { error_msg("Destination object name missing\n"); usage(); leave(EXIT_FAILURE); } /*------------------------------------------------------------------------- * open output file *-------------------------------------------------------------------------*/ /* Attempt to open an existing HDF5 file first. Need to open the dst file before the src file just in case that the dst and src are the same file */ fid_dst = h5tools_fopen(fname_dst, H5F_ACC_RDWR, H5P_DEFAULT, NULL, NULL, 0); /*------------------------------------------------------------------------- * open input file *-------------------------------------------------------------------------*/ fid_src = h5tools_fopen(fname_src, H5F_ACC_RDONLY, H5P_DEFAULT, NULL, NULL, 0); /*------------------------------------------------------------------------- * test for error in opening input file *-------------------------------------------------------------------------*/ if (fid_src==-1) { error_msg("Could not open input file <%s>...Exiting\n", fname_src); leave(EXIT_FAILURE); } /*------------------------------------------------------------------------- * create an output file when failed to open it *-------------------------------------------------------------------------*/ /* If we couldn't open an existing file, try creating file */ /* (use "EXCL" instead of "TRUNC", so we don't blow away existing non-HDF5 file) */ if(fid_dst < 0) fid_dst = H5Fcreate(fname_dst, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT); /*------------------------------------------------------------------------- * test for error in opening output file *-------------------------------------------------------------------------*/ if (fid_dst==-1) { error_msg("Could not open output file <%s>...Exiting\n", fname_dst); leave(EXIT_FAILURE); } /*------------------------------------------------------------------------- * print some info *-------------------------------------------------------------------------*/ if (verbose) { printf("Copying file <%s> and object <%s> to file <%s> and object <%s>\n", fname_src, oname_src, fname_dst, oname_dst); if (flag) { HDassert(str_flag); printf("Using %s flag\n", str_flag); } } /*------------------------------------------------------------------------- * create property lists for copy *-------------------------------------------------------------------------*/ /* create property to pass copy options */ if ( (ocpl_id = H5Pcreate(H5P_OBJECT_COPY)) < 0) goto error; /* set options for object copy */ if (flag) { if ( H5Pset_copy_object(ocpl_id, flag) < 0) goto error; } /* Create link creation property list */ if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) { error_msg("Could not create link creation property list\n"); goto error; } /* end if */ /* Check for creating intermediate groups */ if(parents) { /* Set the intermediate group creation property */ if(H5Pset_create_intermediate_group(lcpl_id, 1) < 0) { error_msg("Could not set property for creating parent groups\n"); goto error; } /* end if */ /* Display some output if requested */ if(verbose) printf("%s: Creating parent groups\n", h5tools_getprogname()); } /* end if */ else /* error, if parent groups doesn't already exist in destination file */ { size_t i, len; len = HDstrlen(oname_dst); /* check if all the parents groups exist. skip root group */ for (i = 1; i < len; i++) { if ('/'==oname_dst[i]) { char *str_ptr; str_ptr = (char *)HDcalloc(i + 1, sizeof(char)); HDstrncpy(str_ptr, oname_dst, i); str_ptr[i]='\0'; if (H5Lexists(fid_dst, str_ptr, H5P_DEFAULT) <= 0) { error_msg("group <%s> doesn't exist. Use -p to create parent groups.\n", str_ptr); HDfree(str_ptr); goto error; } HDfree(str_ptr); } } } /*------------------------------------------------------------------------- * do the copy *-------------------------------------------------------------------------*/ if(verbose) linkinfo.opt.msg_mode = 1; li_ret = H5tools_get_symlink_info(fid_src, oname_src, &linkinfo, 1); if (li_ret == 0) /* dangling link */ { if(H5Lcopy(fid_src, oname_src, fid_dst, oname_dst, H5P_DEFAULT, H5P_DEFAULT) < 0) goto error; } else /* valid link */ { if (H5Ocopy(fid_src, /* Source file or group identifier */ oname_src, /* Name of the source object to be copied */ fid_dst, /* Destination file or group identifier */ oname_dst, /* Name of the destination object */ ocpl_id, /* Object copy property list */ lcpl_id)<0) /* Link creation property list */ goto error; } /* free link info path */ if (linkinfo.trg_path) HDfree(linkinfo.trg_path); /* close propertis */ if(H5Pclose(ocpl_id)<0) goto error; if(H5Pclose(lcpl_id)<0) goto error; /* close files */ if (H5Fclose(fid_src)<0) goto error; if (H5Fclose(fid_dst)<0) goto error; leave(EXIT_SUCCESS); error: printf("Error in copy...Exiting\n"); /* free link info path */ if (linkinfo.trg_path) HDfree(linkinfo.trg_path); H5E_BEGIN_TRY { H5Pclose(ocpl_id); H5Pclose(lcpl_id); H5Fclose(fid_src); H5Fclose(fid_dst); } H5E_END_TRY; leave(EXIT_FAILURE); }
/* * Function: sio_create_filename * Purpose: Create a new filename to write to. Determine the correct * suffix to append to the filename by the type of I/O we're * doing. Also, place in the /tmp/{$USER,$LOGIN} directory if * USER or LOGIN are specified in the environment. * Return: Pointer to filename or NULL * Programmer: Bill Wendling, 21. November 2001 * Modifications: Support for file drivers. Christian Chilan, April, 2008 */ static char * sio_create_filename(iotype iot, const char *base_name, char *fullname, size_t size, parameters *param) { const char *prefix, *suffix=""; char *ptr, last = '\0'; size_t i, j; vfdtype vfd; vfd = param->vfd; if (!base_name || !fullname || size < 1) return NULL; memset(fullname, 0, size); switch (iot) { case POSIXIO: suffix = ".posix"; break; case HDF5: suffix = ".h5"; if (vfd == family) suffix = "%05d.h5"; else if (vfd == multi) suffix = NULL; break; default: /* unknown request */ HDfprintf(stderr, "Unknown IO type request (%d)\n", (int)iot); HDassert(0 && "Unknown IO type"); break; } /* First use the environment variable and then try the constant */ prefix = HDgetenv("HDF5_PREFIX"); #ifdef HDF5_PREFIX if (!prefix) prefix = HDF5_PREFIX; #endif /* HDF5_PREFIX */ /* Prepend the prefix value to the base name */ if (prefix && *prefix) { /* If the prefix specifies the HDF5_PREFIX directory, then * default to using the "/tmp/$USER" or "/tmp/$LOGIN" * directory instead. */ register char *user, *login, *subdir; user = HDgetenv("USER"); login = HDgetenv("LOGIN"); subdir = (user ? user : login); if (subdir) { for (i = 0; i < size-1 && prefix[i]; i++) fullname[i] = prefix[i]; fullname[i++] = '/'; for (j = 0; i < size && subdir[j]; i++, j++) fullname[i] = subdir[j]; } else { /* We didn't append the prefix yet */ HDstrncpy(fullname, prefix, size); fullname[size - 1] = '\0'; } if ((HDstrlen(fullname) + HDstrlen(base_name) + 1) < size) { /* Append the base_name with a slash first. Multiple slashes are * handled below. */ h5_stat_t buf; if (HDstat(fullname, &buf) < 0) /* The directory doesn't exist just yet */ if (HDmkdir(fullname, 0755) < 0 && errno != EEXIST) { /* We couldn't make the "/tmp/${USER,LOGIN}" subdirectory. * Default to PREFIX's original prefix value. */ HDstrcpy(fullname, prefix); } HDstrcat(fullname, "/"); HDstrcat(fullname, base_name); } else { /* Buffer is too small */ return NULL; } } else if (strlen(base_name) >= size) { /* Buffer is too small */ return NULL; } else { HDstrcpy(fullname, base_name); } /* Append a suffix */ if (suffix) { if (HDstrlen(fullname) + HDstrlen(suffix) >= size) return NULL; HDstrcat(fullname, suffix); } /* Remove any double slashes in the filename */ for (ptr = fullname, i = j = 0; ptr && (i < size); i++, ptr++) { if (*ptr != '/' || last != '/') fullname[j++] = *ptr; last = *ptr; } return fullname; }
int main(void) { int nrow = 3, ncol = 4, npln = 5; int i, j, k; FILE *sp; char machine_order[3] = {0, 0, 0}; float row4[3], col4[4], pln4[5]; float rowo4 = 11.0F, colo4 = 21.0F, plno4 = 51.0F; float rowi4 = 1.0F, coli4 = 2.0F, plni4 = 5.0F; int b32i3[5][3][4]; int row4i[3], col4i[4], pln4i[5]; int rowo4i = 11 , colo4i = 21 , plno4i = 51 ; int rowi4i = 1 , coli4i = 2 , plni4i = 5 ; #ifdef H5_SIZEOF_LONG_LONG long long row4i64[3], col4i64[4], pln4i64[5]; long long rowo4i64 = (long long)11 , colo4i64 = (long long)21 , plno4i64 = (long long)51 ; long long rowi4i64 = (long long)1 , coli4i64 = (long long)2 , plni4i64 = (long long)5 ; #endif short b16i3[5][3][4]; short row4i16[3], col4i16[4], pln4i16[5]; short rowo4i16 = (short)11 , colo4i16 = (short)21 , plno4i16 = (short)51 ; short rowi4i16 = (short)1 , coli4i16 = (short)2 , plni4i16 = (short)5 ; char b8i3[5][3][4]; char row4i8[3], col4i8[4], pln4i8[5]; char rowo4i8 = (char)11 , colo4i8 = (char)21 , plno4i8 = (char)51 ; char rowi4i8 = (char)1 , coli4i8 = (char)2 , plni4i8 = (char)5 ; double b64r3[5][3][4]; double row8[3], col8[4], pln8[5]; double rowo8 = 11.0F, colo8 = 21.0F, plno8 = 51.0F; double rowi8 = 1.0F, coli8 = 2.0F, plni8 = 5.0F; /* Initialize machine endian */ volatile uint32_t ibyte=0x01234567; /* 0 for big endian, 1 for little endian. */ if ((*((uint8_t*)(&ibyte))) == 0x67) HDstrncpy(machine_order, "LE", 2); else HDstrncpy(machine_order, "BE", 2); /* * initialize the row, column, and plane vectors * * row values start at 11 and increment by 1 => 11, 12, 13 * column values start at 21 and increment by 2 => 21, 23, 25, 27 * plane values start at 51 and increment by 5 => 51, 56, 61, 66, 71 */ /* * build array elements - rank 2 * * element value = sum of row value and col values */ row4[0] = rowo4; col4[0] = colo4; pln4[0] = plno4; row8[0] = rowo8; col8[0] = colo8; pln8[0] = plno8; row4i[0] = rowo4i; col4i[0] = colo4i; pln4i[0] = plno4i; #ifdef H5_SIZEOF_LONG_LONG row4i64[0] = rowo4i64; col4i64[0] = colo4i64; pln4i64[0] = plno4i64; #endif row4i16[0] = rowo4i16; col4i16[0] = colo4i16; pln4i16[0] = plno4i16; row4i8[0] = rowo4i8; col4i8[0] = colo4i8; pln4i8[0] = plno4i8; for (i = 1; i < nrow; i++) { row4[i] = row4[i - 1] + rowi4; row8[i] = row8[i - 1] + rowi8; row4i[i] = row4i[i - 1] + rowi4i; #ifdef H5_SIZEOF_LONG_LONG row4i64[i] = row4i64[i - 1] + rowi4i64; #endif row4i16[i] = (short)(row4i16[i - 1] + rowi4i16); row4i8[i] = (char)(row4i8[i - 1] + rowi4i8); } for (j = 1; j < ncol; j++) { col4[j] = col4[j - 1] + coli4; col8[j] = col8[j - 1] + coli8; col4i[j] = col4i[j - 1] + coli4i; #ifdef H5_SIZEOF_LONG_LONG col4i64[j] = col4i64[j - 1] + coli4i64; #endif col4i16[j] = (short)(col4i16[j - 1] + coli4i16); col4i8[j] = (char)(col4i8[j - 1] + coli4i8); } for (k = 1; k < npln; k++) { pln4[k] = pln4[k - 1] + plni4; pln8[k] = pln8[k - 1] + plni8; pln4i[k] = pln4i[k - 1] + plni4i; #ifdef H5_SIZEOF_LONG_LONG pln4i64[k] = pln4i64[k - 1] + plni4i64; #endif pln4i16[k] = (short)(pln4i16[k - 1] + plni4i16); pln4i8[k] = (char)(pln4i8[k - 1] + plni4i8); } /* * build array elements - rank 3 * * element value = sum of row value, col, and plane values */ for (i = 0; i < nrow; i++) for (j = 0; j < ncol; j++) for (k = 0; k < npln; k++) { b64r3[k][i][j] = row8[i] + col8[j] + pln8[k]; b32i3[k][i][j] = row4i[i] + col4i[j] + pln4i[k]; b16i3[k][i][j] = (short)(row4i16[i] + col4i16[j] + pln4i16[k]); b8i3[k][i][j] = (char)(row4i8[i] + col4i8[j] + pln4i8[k]); } #ifndef UNICOS #ifdef REBUILDTEXTFILES /*------------------------------------------------------------------------- * TOOLTEST txtin8.txt -c $srcdir/testfiles/txtin8.conf -o txtin8.h5 *------------------------------------------------------------------------- */ sp = HDfopen("txtin8.txt", "w"); for (k = 0; k < npln; k++) { for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) (void) fprintf(sp, "%10u", b8i3[k][i][j]); (void) fprintf(sp, "\n"); } } (void) HDfclose(sp); /*------------------------------------------------------------------------- * TOOLTEST txtin16.txt -c $srcdir/testfiles/txtin16.conf -o txtin16.h5 *------------------------------------------------------------------------- */ sp = HDfopen("txtin16.txt", "w"); for (k = 0; k < npln; k++) { for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) (void) fprintf(sp, "%10u", b16i3[k][i][j]); (void) fprintf(sp, "\n"); } } (void) HDfclose(sp); /*------------------------------------------------------------------------- * TOOLTEST txtin32.txt -c $srcdir/testfiles/textin32.conf -o textin32.h5 *------------------------------------------------------------------------- */ sp = HDfopen("txtin32.txt", "w"); for (k = 0; k < npln; k++) { for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) (void) fprintf(sp, "%10d", b32i3[k][i][j]); (void) fprintf(sp, "\n"); } } (void) HDfclose(sp); #endif /*------------------------------------------------------------------------- * TOOLTEST binin32.bin -c binin32.conf -o binin32.h5 *------------------------------------------------------------------------- */ sp = HDfopen("binin32.bin", OPEN_FLAGS); for (k = 0; k < npln; k++) { for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) { (void) HDfwrite((char *) &b32i3[k][i][j], sizeof(int), 1, sp); } } } (void) HDfclose(sp); sp = HDfopen("binin32.conf", "w"); (void) fprintf(sp, "PATH /int/bin/32-bit\n"); (void) fprintf(sp, "INPUT-CLASS IN\n"); (void) fprintf(sp, "INPUT-SIZE 32\n"); (void) fprintf(sp, "INPUT-BYTE-ORDER %s\n", machine_order); (void) fprintf(sp, "RANK 3\n"); (void) fprintf(sp, "OUTPUT-ARCHITECTURE STD\n"); (void) fprintf(sp, "OUTPUT-BYTE-ORDER BE\n"); (void) fprintf(sp, "DIMENSION-SIZES 5 3 4\n"); (void) fprintf(sp, "CHUNKED-DIMENSION-SIZES 1 2 1\n"); (void) fprintf(sp, "\n"); (void) HDfclose(sp); /*------------------------------------------------------------------------- * TOOLTEST binuin32.bin -c binuin32.conf -o binuin32.h5 *------------------------------------------------------------------------- */ sp = HDfopen("binuin32.bin", OPEN_FLAGS); for (k = 0; k < npln; k++) { for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) { (void) HDfwrite((char *) &b32i3[k][i][j], sizeof(unsigned int), 1, sp); } } } (void) HDfclose(sp); sp = HDfopen("binuin32.conf", "w"); (void) fprintf(sp, "PATH /int/buin/32-bit\n"); (void) fprintf(sp, "INPUT-CLASS UIN\n"); (void) fprintf(sp, "INPUT-SIZE 32\n"); (void) fprintf(sp, "INPUT-BYTE-ORDER %s\n", machine_order); (void) fprintf(sp, "RANK 3\n"); (void) fprintf(sp, "OUTPUT-ARCHITECTURE STD\n"); (void) fprintf(sp, "OUTPUT-BYTE-ORDER LE\n"); (void) fprintf(sp, "DIMENSION-SIZES 5 3 4\n"); (void) fprintf(sp, "\n"); (void) HDfclose(sp); /*------------------------------------------------------------------------- * TOOLTEST binin16.bin -c binin16.conf -o binin16.h5 *------------------------------------------------------------------------- */ sp = HDfopen("binin16.bin", OPEN_FLAGS); for (k = 0; k < npln; k++) { for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) { (void) HDfwrite((char *) &b16i3[k][i][j], sizeof(short), 1, sp); } } } (void) HDfclose(sp); sp = HDfopen("binin16.conf", "w"); (void) fprintf(sp, "PATH /int/bin/16-bit\n"); (void) fprintf(sp, "INPUT-CLASS IN\n"); (void) fprintf(sp, "INPUT-SIZE 16\n"); (void) fprintf(sp, "INPUT-BYTE-ORDER %s\n", machine_order); (void) fprintf(sp, "RANK 3\n"); (void) fprintf(sp, "OUTPUT-ARCHITECTURE STD\n"); (void) fprintf(sp, "OUTPUT-BYTE-ORDER LE\n"); (void) fprintf(sp, "DIMENSION-SIZES 2 3 4\n"); (void) fprintf(sp, "CHUNKED-DIMENSION-SIZES 2 2 2\n"); (void) fprintf(sp, "MAXIMUM-DIMENSIONS -1 -1 8\n"); (void) fprintf(sp, "\n"); (void) HDfclose(sp); /*------------------------------------------------------------------------- * TOOLTEST binuin16.bin -c binuin16.conf -o binuin16.h5 *------------------------------------------------------------------------- */ sp = HDfopen("binuin16.bin", OPEN_FLAGS); for (k = 0; k < npln; k++) { for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) { (void) HDfwrite((char *) &b16i3[k][i][j], sizeof(unsigned short), 1, sp); } } } (void) HDfclose(sp); sp = HDfopen("binuin16.conf", "w"); (void) fprintf(sp, "PATH /int/buin/16-bit\n"); (void) fprintf(sp, "INPUT-CLASS UIN\n"); (void) fprintf(sp, "INPUT-SIZE 16\n"); (void) fprintf(sp, "INPUT-BYTE-ORDER %s\n", machine_order); (void) fprintf(sp, "RANK 3\n"); (void) fprintf(sp, "OUTPUT-ARCHITECTURE STD\n"); (void) fprintf(sp, "OUTPUT-BYTE-ORDER BE\n"); (void) fprintf(sp, "DIMENSION-SIZES 2 3 4\n"); (void) fprintf(sp, "CHUNKED-DIMENSION-SIZES 2 2 2\n"); (void) fprintf(sp, "MAXIMUM-DIMENSIONS -1 -1 8\n"); (void) fprintf(sp, "\n"); (void) HDfclose(sp); /*------------------------------------------------------------------------- * TOOLTEST binin8.bin -c binin8.conf -o binin8.h5 *------------------------------------------------------------------------- */ sp = HDfopen("binin8.bin", OPEN_FLAGS); for (k = 0; k < npln; k++) { for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) { (void) HDfwrite((char *) &b8i3[k][i][j], sizeof(char), 1, sp); } } } (void) HDfclose(sp); sp = HDfopen("binin8.conf", "w"); (void) fprintf(sp, "PATH /int/bin/8-bit\n"); (void) fprintf(sp, "INPUT-CLASS IN\n"); (void) fprintf(sp, "INPUT-SIZE 8\n"); (void) fprintf(sp, "INPUT-BYTE-ORDER %s\n", machine_order); (void) fprintf(sp, "RANK 3\n"); (void) fprintf(sp, "OUTPUT-CLASS IN\n"); (void) fprintf(sp, "OUTPUT-SIZE 16\n"); (void) fprintf(sp, "OUTPUT-ARCHITECTURE STD\n"); (void) fprintf(sp, "OUTPUT-BYTE-ORDER LE\n"); (void) fprintf(sp, "DIMENSION-SIZES 5 3 4\n"); (void) fprintf(sp, "CHUNKED-DIMENSION-SIZES 2 2 2\n"); (void) fprintf(sp, "MAXIMUM-DIMENSIONS -1 -1 -1\n"); (void) fprintf(sp, "COMPRESSION-PARAM 3\n"); (void) fprintf(sp, "\n"); (void) HDfclose(sp); #endif /* UNICOS */ /*------------------------------------------------------------------------- * TOOLTEST binfp64.bin -c binfp64.conf -o binfp64.h5 *------------------------------------------------------------------------- */ /* * binary 64-bit file - rank 2 & 3 */ sp = HDfopen("binfp64.bin", OPEN_FLAGS); for (k = 0; k < npln; k++) { for (i = 0; i < nrow; i++) { for (j = 0; j < ncol; j++) { (void) HDfwrite((char *) &b64r3[k][i][j], sizeof(double), 1, sp); } } } (void) HDfclose(sp); sp = HDfopen("binfp64.conf", "w"); (void) fprintf(sp, "PATH /fp/bin/64-bit\n"); (void) fprintf(sp, "INPUT-CLASS FP\n"); (void) fprintf(sp, "INPUT-SIZE 64\n"); (void) fprintf(sp, "INPUT-BYTE-ORDER %s\n", machine_order); (void) fprintf(sp, "RANK 3\n"); (void) fprintf(sp, "OUTPUT-ARCHITECTURE IEEE\n"); (void) fprintf(sp, "OUTPUT-BYTE-ORDER LE\n"); (void) fprintf(sp, "DIMENSION-SIZES 5 3 4\n"); (void) fprintf(sp, "CHUNKED-DIMENSION-SIZES 2 2 2\n"); (void) fprintf(sp, "MAXIMUM-DIMENSIONS -1 6 7\n"); (void) fprintf(sp, "COMPRESSION-PARAM 8\n"); (void) fprintf(sp, "\n"); (void) HDfclose(sp); /*------------------------------------------------------------------------- * TOOLTEST binin8w.bin -c binin8w.conf -o binin8w.h5 *------------------------------------------------------------------------- */ { /* test CR+LF (13,10) and EOF (26) in windows */ char bin8w[4] = {13,10,26,0}; sp = HDfopen("binin8w.bin", OPEN_FLAGS); for (i = 0; i < 4; i++) { char c = bin8w[i]; if ( HDfwrite( &c, sizeof(char), 1, sp) != 1 ) printf("error writing file\n"); } HDfclose(sp); sp = HDfopen("binin8w.conf", "w"); (void) fprintf(sp, "INPUT-CLASS IN\n"); (void) fprintf(sp, "INPUT-SIZE 8\n"); (void) fprintf(sp, "INPUT-BYTE-ORDER %s\n", machine_order); (void) fprintf(sp, "RANK 1\n"); (void) fprintf(sp, "OUTPUT-CLASS IN\n"); (void) fprintf(sp, "OUTPUT-SIZE 8\n"); (void) fprintf(sp, "OUTPUT-ARCHITECTURE STD\n"); (void) fprintf(sp, "OUTPUT-BYTE-ORDER LE\n"); (void) fprintf(sp, "DIMENSION-SIZES 4\n"); (void) fprintf(sp, "\n"); (void) HDfclose(sp); } return (EXIT_SUCCESS); }
/*------------------------------------------------------------------------- * Function: H5F_read_superblock * * Purpose: Reads the superblock from the file or from the BUF. If * ADDR is a valid address, then it reads it from the file. * If not, then BUF must be non-NULL for it to read from the * BUF. * * Return: Success: SUCCEED * Failure: FAIL * * Programmer: Bill Wendling * [email protected] * Sept 12, 2003 * * Modifications: * *------------------------------------------------------------------------- */ herr_t H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_entry_t *root_ent) { haddr_t stored_eoa; /*relative end-of-addr in file */ haddr_t eof; /*end of file address */ uint8_t *q; /*ptr into temp I/O buffer */ size_t sizeof_addr = 0; size_t sizeof_size = 0; const size_t fixed_size = 24; /*fixed sizeof superblock */ unsigned sym_leaf_k = 0; size_t variable_size; /*variable sizeof superblock */ unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree internal node 'K' values */ H5F_file_t *shared = NULL; /* shared part of `file' */ H5FD_t *lf = NULL; /* file driver part of `shared' */ uint8_t *p; /* Temporary pointer into encoding buffers */ unsigned i; /* Index variable */ unsigned chksum; /* Checksum temporary variable */ size_t driver_size; /* Size of driver info block, in bytes */ char driver_name[9]; /* Name of driver, for driver info block */ unsigned super_vers; /* Super block version */ unsigned freespace_vers; /* Freespace info version */ unsigned obj_dir_vers; /* Object header info version */ unsigned share_head_vers; /* Shared header info version */ uint8_t buf[H5F_SUPERBLOCK_SIZE]; /* Local buffer */ H5P_genplist_t *c_plist; /* File creation property list */ herr_t ret_value = SUCCEED; /* Decoding */ FUNC_ENTER_NOAPI(H5F_read_superblock, FAIL) /* Short cuts */ shared = f->shared; lf = shared->lf; /* Get the shared file creation property list */ if (NULL == (c_plist = H5I_object(shared->fcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") /* Read the superblock if it hasn't been read before. */ if (HADDR_UNDEF == (shared->super_addr=H5F_locate_signature(lf,dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to find file signature") if (H5FD_set_eoa(lf, shared->super_addr + fixed_size) < 0 || H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, shared->super_addr, fixed_size, buf) < 0) HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "unable to read superblock") /* Signature, already checked */ p = buf + H5F_SIGNATURE_LEN; /* Superblock version */ super_vers = *p++; if (super_vers > HDF5_SUPERBLOCK_VERSION_MAX) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad superblock version number") if (H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set superblock version") /* Freespace version */ freespace_vers = *p++; if (HDF5_FREESPACE_VERSION != freespace_vers) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad free space version number") if (H5P_set(c_plist, H5F_CRT_FREESPACE_VERS_NAME, &freespace_vers) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to free space version") /* Root group version number */ obj_dir_vers = *p++; if (HDF5_OBJECTDIR_VERSION != obj_dir_vers) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad object directory version number") if (H5P_set(c_plist, H5F_CRT_OBJ_DIR_VERS_NAME, &obj_dir_vers) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set object directory version") /* Skip over reserved byte */ p++; /* Shared header version number */ share_head_vers = *p++; if (HDF5_SHAREDHEADER_VERSION != share_head_vers) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad shared-header format version number") if (H5P_set(c_plist, H5F_CRT_SHARE_HEAD_VERS_NAME, &share_head_vers) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set shared-header format version") /* Size of file addresses */ sizeof_addr = *p++; if (sizeof_addr != 2 && sizeof_addr != 4 && sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number in an address") if (H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME,&sizeof_addr) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number in an address") shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */ /* Size of file sizes */ sizeof_size = *p++; if (sizeof_size != 2 && sizeof_size != 4 && sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number for object size") if (H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number for object size") shared->sizeof_size = sizeof_size; /* Keep a local copy also */ /* Skip over reserved byte */ p++; /* Various B-tree sizes */ UINT16DECODE(p, sym_leaf_k); if (sym_leaf_k == 0) HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "bad symbol table leaf node 1/2 rank") if (H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for symbol table leaf nodes") shared->sym_leaf_k = sym_leaf_k; /* Keep a local copy also */ /* Need 'get' call to set other array values */ if (H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get rank for btree internal nodes") UINT16DECODE(p, btree_k[H5B_SNODE_ID]); if (btree_k[H5B_SNODE_ID] == 0) HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "bad 1/2 rank for btree internal nodes") /* * Delay setting the value in the property list until we've checked * for the indexed storage B-tree internal 'K' value later. */ /* File consistency flags. Not really used yet */ UINT32DECODE(p, shared->consist_flags); assert(((size_t)(p - buf)) == fixed_size); /* Decode the variable-length part of the superblock... */ variable_size = (super_vers>0 ? 4 : 0) + /* Potential indexed storage B-tree internal 'K' value */ H5F_SIZEOF_ADDR(f) + /*base addr*/ H5F_SIZEOF_ADDR(f) + /*global free list*/ H5F_SIZEOF_ADDR(f) + /*end-of-address*/ H5F_SIZEOF_ADDR(f) + /*reserved address*/ H5G_SIZEOF_ENTRY(f); /*root group ptr*/ assert(fixed_size + variable_size <= sizeof(buf)); if (H5FD_set_eoa(lf, shared->super_addr + fixed_size+variable_size) < 0 || H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, shared->super_addr + fixed_size, variable_size, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read superblock") /* * If the superblock version # is greater than 0, read in the indexed * storage B-tree internal 'K' value */ if (super_vers > 0) { UINT16DECODE(p, btree_k[H5B_ISTORE_ID]); p += 2; /* reserved */ } else btree_k[H5B_ISTORE_ID] = HDF5_BTREE_ISTORE_IK_DEF; /* Set the B-tree internal node values, etc */ if (H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for btree internal nodes") HDmemcpy(shared->btree_k, btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID); /* Keep a local copy also */ H5F_addr_decode(f, (const uint8_t **)&p, &shared->base_addr/*out*/); H5F_addr_decode(f, (const uint8_t **)&p, &shared->freespace_addr/*out*/); H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/); H5F_addr_decode(f, (const uint8_t **)&p, &shared->driver_addr/*out*/); if (H5G_ent_decode(f, (const uint8_t **)&p, root_ent/*out*/) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read root symbol entry") /* * Check if superblock address is different from base address and * adjust base address and "end of address" address if so. */ if (!H5F_addr_eq(shared->super_addr,shared->base_addr)) { /* Check if the superblock moved earlier in the file */ if (H5F_addr_lt(shared->super_addr, shared->base_addr)) stored_eoa -= (shared->base_addr - shared->super_addr); else /* The superblock moved later in the file */ stored_eoa += (shared->super_addr - shared->base_addr); shared->base_addr = shared->super_addr; } /* end if */ /* Compute super block checksum */ assert(sizeof(chksum) == sizeof(shared->super_chksum)); for (q = (uint8_t *)&chksum, chksum = 0, i = 0; i < fixed_size + variable_size; ++i) q[i % sizeof(shared->super_chksum)] ^= buf[i]; /* Set the super block checksum */ shared->super_chksum = chksum; /* Decode the optional driver information block */ if (H5F_addr_defined(shared->driver_addr)) { haddr_t drv_addr = shared->base_addr + shared->driver_addr; uint8_t dbuf[H5F_DRVINFOBLOCK_SIZE]; /* Local buffer */ if (H5FD_set_eoa(lf, drv_addr + 16) < 0 || H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr, (size_t)16, dbuf) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read driver information block") p = dbuf; /* Version number */ if (HDF5_DRIVERINFO_VERSION != *p++) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad driver information block version number") p += 3; /* reserved */ /* Driver info size */ UINT32DECODE(p, driver_size); /* Driver name and/or version */ HDstrncpy(driver_name, (const char *)p, (size_t)8); driver_name[8] = '\0'; p += 8; /* advance past name/version */ /* Read driver information and decode */ assert((driver_size + 16) <= sizeof(dbuf)); if (H5FD_set_eoa(lf, drv_addr + 16 + driver_size) < 0 || H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr+16, driver_size, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read file driver information") if (H5FD_sb_decode(lf, driver_name, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to decode driver information") /* Compute driver info block checksum */ assert(sizeof(chksum) == sizeof(shared->drvr_chksum)); for (q = (uint8_t *)&chksum, chksum = 0, i = 0; i < (driver_size + 16); ++i) q[i % sizeof(shared->drvr_chksum)] ^= dbuf[i]; /* Set the driver info block checksum */ shared->drvr_chksum = chksum; } /* end if */