diff options
Diffstat (limited to 'src/H5F.c')
-rw-r--r-- | src/H5F.c | 1848 |
1 files changed, 940 insertions, 908 deletions
@@ -1,21 +1,21 @@ /**************************************************************************** -* NCSA HDF * -* Software Development Group * -* National Center for Supercomputing Applications * -* University of Illinois at Urbana-Champaign * -* 605 E. Springfield, Champaign IL 61820 * -* * -* For conditions of distribution and use, see the accompanying * -* hdf/COPYING file. * +* NCSA HDF * +* Software Development Group * +* National Center for Supercomputing Applications * +* University of Illinois at Urbana-Champaign * +* 605 E. Springfield, Champaign IL 61820 * +* * +* For conditions of distribution and use, see the accompanying * +* hdf/COPYING file. * * * MODIFICATIONS -* Robb Matzke, 30 Aug 1997 -* Added `ERRORS' fields to function prologues. -* * +* Robb Matzke, 30 Aug 1997 +* Added `ERRORS' fields to function prologues. +* * ****************************************************************************/ #ifdef RCSID -static char RcsId[] = "@(#)$Revision$"; +static char RcsId[] = "@(#)$Revision$"; #endif /* $Id$ */ @@ -27,24 +27,24 @@ static char RcsId[] = "@(#)$Revision$"; HDF5 file I/O routines EXPORTED ROUTINES - H5Fcreate -- Create an HDF5 file - H5Fclose -- Close an open HDF5 file + H5Fcreate -- Create an HDF5 file + H5Fclose -- Close an open HDF5 file LIBRARY-SCOPED ROUTINES LOCAL ROUTINES - H5F_init_interface -- initialize the H5F interface + H5F_init_interface -- initialize the H5F interface */ /* Packages needed by this file... */ -#include <H5private.h> /*library functions */ -#include <H5Aprivate.h> /*atoms */ -#include <H5ACprivate.h> /*cache */ -#include <H5Cprivate.h> /*templates */ -#include <H5Eprivate.h> /*error handling */ -#include <H5Gprivate.h> /*symbol tables */ -#include <H5Mprivate.h> /*meta data */ -#include <H5MMprivate.h> /*core memory management */ +#include <H5private.h> /*library functions */ +#include <H5Aprivate.h> /*atoms */ +#include <H5ACprivate.h> /*cache */ +#include <H5Cprivate.h> /*templates */ +#include <H5Eprivate.h> /*error handling */ +#include <H5Gprivate.h> /*symbol tables */ +#include <H5Mprivate.h> /*meta data */ +#include <H5MMprivate.h> /*core memory management */ #include <ctype.h> #include <sys/types.h> @@ -57,58 +57,53 @@ static char RcsId[] = "@(#)$Revision$"; */ /* #define H5F_OPT_SEEK */ -#define PABLO_MASK H5F_mask +#define PABLO_MASK H5F_mask -/*--------------------- Locally scoped variables -----------------------------*/ +/*-------------------- Locally scoped variables -----------------------------*/ /* * Define the default file creation template. */ -const H5F_create_t H5F_create_dflt = { - 0, /* Default user-block size */ - 4, /* Default 1/2 rank for symtab leaf nodes */ - { /* Default 1/2 rank for btree intern nodes */ - 16, /* Symbol table internal nodes */ - 32, /* Indexed storage internal nodes */ - 0, /* unused */ - 0, /* unused */ - 0, /* unused */ - 0, /* unused */ - 0, /* unused */ - 0, /* unused */ +const H5F_create_t H5F_create_dflt = { + 0, /* Default user-block size */ + 4, /* Default 1/2 rank for symtab leaf nodes */ + { /* Default 1/2 rank for btree intern nodes */ + 16, /* Symbol table internal nodes */ + 32, /* Indexed storage internal nodes */ + 0, /* unused */ + 0, /* unused */ + 0, /* unused */ + 0, /* unused */ + 0, /* unused */ + 0, /* unused */ }, - 4, /* Default offset size */ - 4, /* Default length size */ - HDF5_BOOTBLOCK_VERSION, /* Current Boot-Block version # */ - HDF5_SMALLOBJECT_VERSION, /* Current Small-Object heap version # */ - HDF5_FREESPACE_VERSION, /* Current Free-Space info version # */ - HDF5_OBJECTDIR_VERSION, /* Current Object Directory info version # */ - HDF5_SHAREDHEADER_VERSION, /* Current Shared-Header format version # */ + 4, /* Default offset size */ + 4, /* Default length size */ + HDF5_BOOTBLOCK_VERSION, /* Current Boot-Block version # */ + HDF5_SMALLOBJECT_VERSION, /* Current Small-Object heap version # */ + HDF5_FREESPACE_VERSION, /* Current Free-Space info version # */ + HDF5_OBJECTDIR_VERSION, /* Current Object Directory info version # */ + HDF5_SHAREDHEADER_VERSION, /* Current Shared-Header format version # */ }; /* - * Define the default file access template. + * Define the default file access template. The template is initialized by + * H5F_init_interface(). */ -const H5F_access_t H5F_access_dflt = -{ - H5ACC_DEFAULT, /* Default file access mode */ -#ifdef HAVE_PARALLEL - MPI_COMM_NULL, /* Default is not using MPIO */ - MPI_INFO_NULL, /* Default no info */ -#endif -}; +H5F_access_t H5F_access_dflt; /* Interface initialization */ -static intn interface_initialize_g = FALSE; +static intn interface_initialize_g = FALSE; #define INTERFACE_INIT H5F_init_interface -static herr_t H5F_init_interface(void); -static void H5F_term_interface(void); +static void H5F_term_interface(void); /* PRIVATE PROTOTYPES */ -static H5F_t *H5F_new(H5F_file_t *shared); -static H5F_t *H5F_dest(H5F_t *f); -static herr_t H5F_flush(H5F_t *f, hbool_t invalidate); -static herr_t H5F_locate_signature(H5F_low_t *f_handle, haddr_t *addr /*out */ ); +static H5F_t *H5F_new(H5F_file_t *shared); +static H5F_t *H5F_dest(H5F_t *f); +static herr_t H5F_flush(H5F_t *f, hbool_t invalidate); +static herr_t H5F_locate_signature(H5F_low_t *f_handle, + const H5F_access_t *access_parms, + haddr_t *addr/*out*/); /*-------------------------------------------------------------------------- @@ -130,19 +125,43 @@ Modifications: It was already H5F_mask for the PABLO_TRACE_ON call. --------------------------------------------------------------------------*/ -static herr_t +herr_t H5F_init_interface(void) { - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; + FUNC_ENTER(H5F_init_interface, FAIL); /* Initialize the atom group for the file IDs */ - if ((ret_value = H5A_init_group(H5_FILE, H5A_FILEID_HASHSIZE, 0, - (herr_t (*)(void*))H5Fclose)) != FAIL) - ret_value = H5_add_exit(&H5F_term_interface); + if (H5A_init_group(H5_FILE, H5A_FILEID_HASHSIZE, 0, + (herr_t (*)(void*))H5Fclose)<0 || + H5_add_exit(H5F_term_interface)<0) { + HRETURN_ERROR (H5E_ATOM, H5E_CANTINIT, FAIL, + "unable to initialize interface"); + } + + /* Initialize the default file access template */ + H5F_access_dflt.driver = H5F_LOW_DFLT; + switch (H5F_LOW_DFLT) { + case H5F_LOW_STDIO: + case H5F_LOW_SEC2: + case H5F_LOW_CORE: + case H5F_LOW_SPLIT: + case H5F_LOW_FAMILY: + /* nothing more to init */ + break; + + case H5F_LOW_MPIO: +#ifdef HAVE_PARALLEL + H5F_access_dflt.u.mpio.access_mode = 0; + H5F_access_dflt.u.mpio.comm = MPI_COMM_NULL; + H5F_access_dflt.u.mpio.info = MPI_INFO_NULL; +#endif + break; + } FUNC_LEAVE(ret_value); -} /* H5F_init_interface */ +} /*-------------------------------------------------------------------------- @@ -174,9 +193,9 @@ H5F_term_interface(void) H5F_encode_length_unusual -- encode an unusual length size USAGE void H5F_encode_length_unusual(f, p, l) - const H5F_t *f; IN: pointer to the file record - uint8 **p; IN: pointer to buffer pointer to encode length in - uint8 *l; IN: pointer to length to encode + const H5F_t *f; IN: pointer to the file record + uint8 **p; IN: pointer to buffer pointer to encode length in + uint8 *l; IN: pointer to length to encode ERRORS @@ -188,89 +207,132 @@ H5F_term_interface(void) void H5F_encode_length_unusual(const H5F_t *f, uint8 **p, uint8 *l) { - intn i = (intn)H5F_SIZEOF_SIZE(f)-1; + intn i = (intn)H5F_SIZEOF_SIZE(f)-1; #ifdef WORDS_BIGENDIAN /* * For non-little-endian platforms, encode each byte in memory backwards. */ - for (; i >= 0; i--, (*p)++) - *(*p) = *(l + i); + for (; i >= 0; i--, (*p)++) *(*p) = *(l + i); #else /* platform has little-endian integers */ HDmemcpy(*p,l,i+1); *p+=(i+1); #endif -#ifdef LATER - done: - if (ret_value == FALSE) { /* Error condition cleanup */ - - } /* end if */ -#endif /* LATER */ - - /* Normal function cleanup */ - -} /* H5F_encode_length_unusual */ +} -/*-------------------------------------------------------------------------- - NAME - H5Fget_create_template - - PURPOSE - Get an atom for a copy of the file-creation template for this file - - USAGE - hid_t H5Fget_create_template(fid) - hid_t fid; IN: File ID - - ERRORS - ATOM BADATOM Can't get file struct. - FUNC CANTCREATE Can't create template. - FUNC CANTINIT Can't init template. - - RETURNS - Returns template ID on success, FAIL on failure - - DESCRIPTION - This function returns an atom with a copy of the template parameters - used to create a file. ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Fget_create_template + * + * Purpose: Get an atom for a copy of the file-creation template for this + * file. This function returns an atom with a copy of the + * template parameters used to create a file. + * + * Return: Success: template ID + * + * Failure: FAIL + * + * Programmer: Unknown + * + * Modifications: + * + * Robb Matzke, 18 Feb 1998 + * Calls H5C_copy() to copy the template and H5C_close() to free that + * template if an error occurs. + * + *------------------------------------------------------------------------- + */ hid_t H5Fget_create_template(hid_t fid) { - H5F_t *file = NULL; - hid_t ret_value = FAIL; - H5F_create_t *tmpl = NULL; + H5F_t *file = NULL; + hid_t ret_value = FAIL; + H5F_create_t *tmpl = NULL; FUNC_ENTER(H5Fget_create_template, FAIL); /* check args */ - if (H5_FILE != H5A_group(fid)) { - HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a file"); - } - if (NULL == (file = H5A_object(fid))) { - HRETURN_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't get file struct"); + if (H5_FILE != H5A_group(fid) || NULL==(file=H5A_object (fid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file"); } + /* Create the template object to return */ - tmpl = H5MM_xmalloc(sizeof(H5F_create_t)); - *tmpl = file->shared->create_parms; + if (NULL==(tmpl=H5C_copy (H5C_FILE_CREATE, + &(file->shared->create_parms)))) { + HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL, + "unable to copy file creation properties"); + } + + /* Create an atom */ if ((ret_value = H5C_create(H5C_FILE_CREATE, tmpl)) < 0) { - HRETURN_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, - "can't register template"); + H5C_close (H5C_FILE_CREATE, tmpl); + HRETURN_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to register property list"); } + FUNC_LEAVE(ret_value); } +/*------------------------------------------------------------------------- + * Function: H5Fget_access_template + * + * Purpose: Returns a copy of the file access template of the specified + * file. + * + * Return: Success: Object ID for a copy of the file access + * template. + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, February 18, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5Fget_access_template (hid_t file_id) +{ + H5F_t *f = NULL; + H5F_access_t *tmpl = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER (H5Fget_access_template, FAIL); + + /* Check args */ + if (H5_FILE!=H5A_group (file_id) || NULL==(f=H5A_object (file_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file"); + } + + /* Create the template object to return */ + if (NULL==(tmpl=H5C_copy (H5C_FILE_ACCESS, + &(f->shared->access_parms)))) { + HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL, + "unable to copy file access properties"); + } + + /* Create an atom */ + if ((ret_value = H5C_create (H5C_FILE_ACCESS, tmpl))<0) { + H5C_close (H5C_FILE_ACCESS, tmpl); + HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to register property list"); + } + + FUNC_LEAVE (ret_value); +} + + /*-------------------------------------------------------------------------- NAME H5F_compare_files -- compare file objects for the atom API USAGE intn HPcompare_filename(obj, key) - const void * obj; IN: pointer to the file record - const void * key; IN: pointer to the search key + const void * obj; IN: pointer to the file record + const void * key; IN: pointer to the search key ERRORS @@ -283,55 +345,57 @@ H5Fget_create_template(hid_t fid) static intn H5F_compare_files(const void * _obj, const void * _key) { - const H5F_t *obj = (const H5F_t *) _obj; - const H5F_search_t *key = (const H5F_search_t *) _key; - int ret_value = FALSE; + const H5F_t *obj = (const H5F_t *) _obj; + const H5F_search_t *key = (const H5F_search_t *) _key; + int ret_value = FALSE; FUNC_ENTER(H5F_compare_files, FALSE); ret_value = (obj->shared->key.dev == key->dev && - obj->shared->key.ino == key->ino); + obj->shared->key.ino == key->ino); FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5F_locate_signature + * Function: H5F_locate_signature * - * Purpose: Finds the HDF5 boot block signature in a file. The signature - * can appear at address 0, or any power of two beginning with - * 512. + * Purpose: Finds the HDF5 boot block signature in a file. The signature + * can appear at address 0, or any power of two beginning with + * 512. * - * Return: Success: SUCCEED. The address of the signature is - * returned through the ADDR argument. + * Return: Success: SUCCEED. The address of the signature is + * returned through the ADDR argument. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Friday, November 7, 1997 + * Programmer: Robb Matzke + * Friday, November 7, 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t -H5F_locate_signature(H5F_low_t *f_handle, haddr_t *addr /*out */ ) +H5F_locate_signature(H5F_low_t *f_handle, const H5F_access_t *access_parms, + haddr_t *addr/*out*/) { - haddr_t max_addr; - uint8 buf[H5F_SIGNATURE_LEN]; - uintn n = 9; + haddr_t max_addr; + uint8 buf[H5F_SIGNATURE_LEN]; + uintn n = 9; FUNC_ENTER(H5F_locate_signature, FAIL); H5F_low_size(f_handle, &max_addr); H5F_addr_reset(addr); while (H5F_addr_lt(addr, &max_addr)) { - if (H5F_low_read(f_handle, addr, H5F_SIGNATURE_LEN, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't read file"); - } - if (!HDmemcmp(buf, H5F_SIGNATURE, H5F_SIGNATURE_LEN)) - break; - H5F_addr_pow2(n++, addr); + if (H5F_low_read(f_handle, access_parms, addr, + H5F_SIGNATURE_LEN, buf) < 0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't read file"); + } + if (!HDmemcmp(buf, H5F_SIGNATURE, H5F_SIGNATURE_LEN)) + break; + H5F_addr_pow2(n++, addr); } FUNC_LEAVE(SUCCEED); @@ -347,14 +411,14 @@ H5F_locate_signature(H5F_low_t *f_handle, haddr_t *addr /*out */ ) USAGE hbool_t H5Fis_hdf5(filename) - const char *filename; IN: Name of the file to check + const char *filename; IN: Name of the file to check ERRORS - ARGS BADRANGE No filename specified. - FILE BADFILE Low-level file open failure. - IO READERROR Read error. - IO READERROR Seek error. - IO SEEKERROR Unable to determine length of file due to seek - failure. + ARGS BADRANGE No filename specified. + FILE BADFILE Low-level file open failure. + IO READERROR Read error. + IO READERROR Seek error. + IO SEEKERROR Unable to determine length of file due to seek + failure. RETURNS TRUE/FALSE/FAIL @@ -365,71 +429,80 @@ H5F_locate_signature(H5F_low_t *f_handle, haddr_t *addr /*out */ ) hbool_t H5Fis_hdf5(const char *filename) { - H5F_low_t *f_handle = NULL; /* file handle */ - haddr_t addr; /* Address of file signature & header */ - hbool_t ret_value = FALSE; + H5F_low_t *f_handle = NULL; /* file handle */ + haddr_t addr; /* Address of file signature & header */ + hbool_t ret_value = FALSE; + const H5F_low_class_t *type = NULL; FUNC_ENTER(H5Fis_hdf5, FAIL); /* Check args and all the boring stuff. */ - if (filename == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no filename specified"); + if (filename == NULL) { + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no filename specified"); + } - /* Open the file */ - if (NULL == (f_handle = H5F_low_open(H5F_LOW_DFLT, filename, 0, NULL))) { - HGOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, - "low-level file open failure"); + /* Open the file at the low level driver */ + type = H5F_low_class (H5F_access_dflt.driver); + assert (type); + if (NULL == (f_handle = H5F_low_open(type, filename, &H5F_access_dflt, + 0, NULL))) { + HGOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, + "low-level file open failure"); } - if (H5F_locate_signature(f_handle, &addr) >= 0) { - ret_value = TRUE; + if (H5F_locate_signature(f_handle, &H5F_access_dflt, &addr) >= 0) { + ret_value = TRUE; } + done: - H5F_low_close(f_handle); /* close the file we opened */ + if (f_handle) { + H5F_low_close(f_handle, &H5F_access_dflt); /*close the file we opened*/ + } + FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5F_new + * Function: H5F_new * - * Purpose: Creates a new file object and initializes it. The - * H5Fopen and H5Fcreate functions then fill in various - * fields. If SHARED is a non-null pointer then the shared info - * to which it points has the reference count incremented. - * Otherwise a new, empty shared info struct is created. + * Purpose: Creates a new file object and initializes it. The + * H5Fopen and H5Fcreate functions then fill in various + * fields. If SHARED is a non-null pointer then the shared info + * to which it points has the reference count incremented. + * Otherwise a new, empty shared info struct is created. * * Errors: * - * Return: Success: Ptr to a new file struct. + * Return: Success: Ptr to a new file struct. * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 18 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 18 1997 * * Modifications: * *------------------------------------------------------------------------- */ -static H5F_t * +static H5F_t * H5F_new(H5F_file_t *shared) { - H5F_t *f = NULL; + H5F_t *f = NULL; FUNC_ENTER(H5F_new, NULL); f = H5MM_xcalloc(1, sizeof(H5F_t)); f->shared = shared; if (!f->shared) { - f->shared = H5MM_xcalloc(1, sizeof(H5F_file_t)); - H5F_addr_undef(&(f->shared->boot_addr)); - H5F_addr_undef(&(f->shared->base_addr)); - H5F_addr_undef(&(f->shared->smallobj_addr)); - H5F_addr_undef(&(f->shared->freespace_addr)); - H5F_addr_undef(&(f->shared->hdf5_eof)); - - /* Create a main cache */ - H5AC_create(f, H5AC_NSLOTS); + f->shared = H5MM_xcalloc(1, sizeof(H5F_file_t)); + H5F_addr_undef(&(f->shared->boot_addr)); + H5F_addr_undef(&(f->shared->base_addr)); + H5F_addr_undef(&(f->shared->smallobj_addr)); + H5F_addr_undef(&(f->shared->freespace_addr)); + H5F_addr_undef(&(f->shared->hdf5_eof)); + + /* Create a main cache */ + H5AC_create(f, H5AC_NSLOTS); } f->shared->nrefs++; @@ -437,221 +510,174 @@ H5F_new(H5F_file_t *shared) } /*------------------------------------------------------------------------- - * Function: H5F_dest + * Function: H5F_dest * - * Purpose: Destroys a file structure. This function does not flush - * the cache or anything else; it only frees memory associated - * with the file struct. The shared info for the file is freed - * only when its reference count reaches zero. + * Purpose: Destroys a file structure. This function does not flush + * the cache or anything else; it only frees memory associated + * with the file struct. The shared info for the file is freed + * only when its reference count reaches zero. * * Errors: * - * Return: Success: NULL + * Return: Success: NULL * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 18 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 18 1997 * * Modifications: * *------------------------------------------------------------------------- */ -static H5F_t * +static H5F_t * H5F_dest(H5F_t *f) { FUNC_ENTER(H5F_dest, NULL); if (f) { - if (0 == --(f->shared->nrefs)) { - H5AC_dest(f); - f->shared->root_ent = H5MM_xfree(f->shared->root_ent); - f->shared = H5MM_xfree(f->shared); - } - f->name = H5MM_xfree(f->name); - H5MM_xfree(f); + if (0 == --(f->shared->nrefs)) { + H5AC_dest(f); + f->shared->root_ent = H5MM_xfree(f->shared->root_ent); + f->shared = H5MM_xfree(f->shared); + } + f->name = H5MM_xfree(f->name); + H5MM_xfree(f); } FUNC_LEAVE(NULL); } /*------------------------------------------------------------------------- - * Function: H5F_open - * - * Purpose: Opens (or creates) a file. This function understands the - * following flags which are similar in nature to the Posix - * open(2) flags. + * Function: H5F_open * - * H5F_ACC_WRITE: Open with read/write access. If the file is - * currently open for read-only access then it - * will be reopened. Absence of this flag - * implies read-only access. + * Purpose: Opens (or creates) a file. This function understands the + * following flags which are similar in nature to the Posix + * open(2) flags. * - * H5F_ACC_CREAT: Create a new file if it doesn't exist yet. - * The permissions are 0666 bit-wise AND with - * the current umask. H5F_ACC_WRITE must also - * be specified. + * H5F_ACC_WRITE: Open with read/write access. If the file is + * currently open for read-only access then it + * will be reopened. Absence of this flag + * implies read-only access. * - * H5F_ACC_EXCL: This flag causes H5F_open() to fail if the - * file already exists. + * H5F_ACC_CREAT: Create a new file if it doesn't exist yet. + * The permissions are 0666 bit-wise AND with + * the current umask. H5F_ACC_WRITE must also + * be specified. * - * H5F_ACC_TRUNC: The file is truncated and a new HDF5 boot - * block is written. This operation will fail - * if the file is already open. + * H5F_ACC_EXCL: This flag causes H5F_open() to fail if the + * file already exists. * - * Unlinking the file name from the group directed graph while - * the file is opened causes the file to continue to exist but - * one will not be able to upgrade the file from read-only - * access to read-write access by reopening it. Disk resources - * for the file are released when all handles to the file are - * closed. NOTE: This paragraph probably only applies to Unix; - * deleting the file name in other OS's has undefined results. + * H5F_ACC_TRUNC: The file is truncated and a new HDF5 boot + * block is written. This operation will fail + * if the file is already open. * - * The CREATE_PARMS argument is optional. A null pointer will - * cause the default file creation parameters to be used. + * Unlinking the file name from the group directed graph while + * the file is opened causes the file to continue to exist but + * one will not be able to upgrade the file from read-only + * access to read-write access by reopening it. Disk resources + * for the file are released when all handles to the file are + * closed. NOTE: This paragraph probably only applies to Unix; + * deleting the file name in other OS's has undefined results. * - * The ACCESS_PARMS argument is not used yet. + * The CREATE_PARMS argument is optional. A null pointer will + * cause the default file creation parameters to be used. * - * The TYPE argument determins the low-level type of file that - * is opened. The special value H5F_LOW_DFLT uses the default - * method which is defined at compile time. + * The ACCESS_PARMS argument is optional. A null pointer will + * cause the default file access parameters to be used. * * Errors: - * ATOM BADATOM Can't unatomize default template - * id. - * FILE BADVALUE Can't create file without write - * intent. - * FILE BADVALUE Can't truncate without write intent. - * FILE CANTCREATE Can't create file. - * FILE CANTCREATE Can't truncate file. - * FILE CANTINIT Can't get default file create template - * id. - * FILE CANTINIT Can't write file boot block. - * FILE CANTOPENFILE Bad address size. - * FILE CANTOPENFILE Bad boot block version number. - * FILE CANTOPENFILE Bad free space version number. - * FILE CANTOPENFILE Bad length size. - * FILE CANTOPENFILE Bad object dir version number. - * FILE CANTOPENFILE Bad shared header version number. - * FILE CANTOPENFILE Bad small object heap version number. - * FILE CANTOPENFILE Bad symbol table internal node 1/2 - * rank. - * FILE CANTOPENFILE Bad symbol table leaf node 1/2 rank. - * FILE CANTOPENFILE Can't read root symbol entry. - * FILE CANTOPENFILE Cannot open existing file. - * FILE CANTOPENFILE File cannot be reopened with write - * access. - * FILE CANTOPENFILE File does not exist. - * FILE CANTOPENFILE Invalid file family name. - * FILE FILEEXISTS File already exists - CREAT EXCL - * failed. - * FILE FILEOPEN File already open - TRUNC failed. - * FILE NOTHDF5 Can't find signature. - * FILE NOTHDF5 Can't read boot block. - * FILE READERROR File is not readable. - * FILE TRUNCATED Truncated file? - * FILE WRITEERROR File is not writable. - * IO READERROR Can't read boot block. - * - * Return: Success: Ptr to the file pointer. - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Tuesday, September 23, 1997 + * ATOM BADATOM Can't unatomize default template + * id. + * FILE BADVALUE Can't create file without write + * intent. + * FILE BADVALUE Can't truncate without write intent. + * FILE CANTCREATE Can't create file. + * FILE CANTCREATE Can't truncate file. + * FILE CANTINIT Can't get default file create template + * id. + * FILE CANTINIT Can't write file boot block. + * FILE CANTOPENFILE Bad address size. + * FILE CANTOPENFILE Bad boot block version number. + * FILE CANTOPENFILE Bad free space version number. + * FILE CANTOPENFILE Bad length size. + * FILE CANTOPENFILE Bad object dir version number. + * FILE CANTOPENFILE Bad shared header version number. + * FILE CANTOPENFILE Bad small object heap version number. + * FILE CANTOPENFILE Bad symbol table internal node 1/2 + * rank. + * FILE CANTOPENFILE Bad symbol table leaf node 1/2 rank. + * FILE CANTOPENFILE Can't read root symbol entry. + * FILE CANTOPENFILE Cannot open existing file. + * FILE CANTOPENFILE File cannot be reopened with write + * access. + * FILE CANTOPENFILE File does not exist. + * FILE CANTOPENFILE Invalid file family name. + * FILE FILEEXISTS File already exists - CREAT EXCL + * failed. + * FILE FILEOPEN File already open - TRUNC failed. + * FILE NOTHDF5 Can't find signature. + * FILE NOTHDF5 Can't read boot block. + * FILE READERROR File is not readable. + * FILE TRUNCATED Truncated file? + * FILE WRITEERROR File is not writable. + * IO READERROR Can't read boot block. + * + * Return: Success: Ptr to the file pointer. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Tuesday, September 23, 1997 * * Modifications: * - * Robb Matzke, 11 Nov 1997 - * If the name contains the pattern /[^%]%\d*[duxX]/ then the file is - * assumed to be a family of files. The TYPE argument is ignored and - * H5F_LOW_FAM is used instead. + * Robb Matzke, 11 Nov 1997 + * If the name contains the pattern /[^%]%\d*[duxX]/ then the file is + * assumed to be a family of files. The TYPE argument is ignored and + * H5F_LOW_FAM is used instead. + * + * Albert Cheng, 5 Feb 1998 + * Added the access_parms argument to pass down access template + * information. * - * Albert Cheng, 5 Feb 1998 - * Added the access_parms argument to pass down access template - * information. + * Robb Matzke, 18 Feb 1998 + * The H5F_access_t changed to allow more generality. The low level + * driver is part of the file access template so the TYPE argument has + * been removed. * *------------------------------------------------------------------------- */ -H5F_t * -H5F_open(const H5F_low_class_t *type, const char *name, uintn flags, - const H5F_create_t *create_parms, const H5F_access_t *access_parms) +H5F_t * +H5F_open(const char *name, uintn flags, + const H5F_create_t *create_parms, const H5F_access_t *access_parms) { - H5F_t *f = NULL; /*return value */ - H5F_t *ret_value = NULL; /*a copy of `f' */ - H5F_t *old = NULL; /*a file already opened */ - H5F_search_t search; /*file search key */ - H5F_low_t *fd = NULL; /*low level file desc */ - hbool_t empty_file = FALSE; /*is file empty? */ - hbool_t file_exists = FALSE; /*file already exists */ - uint8 buf[256]; /*I/O buffer.. */ - const uint8 *p = NULL; /* ..and pointer into it */ - size_t fixed_size = 24; /*size of fixed part of boot blk */ - size_t variable_size; /*variable part of boot block */ - H5F_create_t *cp = NULL; /*file creation parameters */ - haddr_t addr1, addr2; /*temporary address */ - H5G_entry_t root_ent; /*root symbol table entry */ - const char *s = name; + H5F_t *f = NULL; /*return value */ + H5F_t *ret_value = NULL; /*a copy of `f' */ + H5F_t *old = NULL; /*a file already opened */ + H5F_search_t search; /*file search key */ + H5F_low_t *fd = NULL; /*low level file desc */ + hbool_t empty_file = FALSE; /*is file empty? */ + hbool_t file_exists = FALSE; /*file already exists */ + uint8 buf[256]; /*I/O buffer.. */ + const uint8 *p = NULL; /* ..and pointer into it */ + size_t fixed_size = 24; /*size of fixed part of boot blk*/ + size_t variable_size; /*variable part of boot block */ + H5F_create_t *cp = NULL; /*file creation parameters */ + haddr_t addr1, addr2; /*temporary address */ + H5G_entry_t root_ent; /*root symbol table entry */ + const H5F_low_class_t *type = NULL; /*low-level file driver */ FUNC_ENTER(H5F_open, NULL); assert(name && *name); /* - * Does the name look like a family name? A family name always has a - * percent (not preceded by a percent) followed by an optional plus and/or - * minus, followed by optional digits, followed by the letter `d', `u', - * `x', or `X'. This is a printf() format for an integer. - */ - while (*s) { - if ('%' != *s++) - continue; - if ('%' == *s) { - s++; - continue; - } - while (*s && isdigit(*s)) - s++; - if ('d' != *s && 'u' != *s && 'x' != *s && 'X' != *s) - continue; - break; - } - if (*s) { -#ifdef H5F_DEBUG - if (type != H5F_LOW_FAM) { - fprintf(stderr, "HDF5-DIAG: opening a file family\n"); - } -#endif - type = H5F_LOW_FAM; - } else if (type == H5F_LOW_FAM) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "invalid file family name"); - } - /* - * If the name ends with `.h5' and there's another file that ends with - * `.raw' then open the file as a split file. - */ - { - if (H5F_LOW_SPLIT != type && (s = strstr(name, ".h5")) && !s[3]) { - char fullname[4096]; - strncpy(fullname, name, s - name); - strcpy(fullname + (s - name), ".raw"); - if (H5F_low_access(H5F_LOW_DFLT, fullname, F_OK, NULL)) { -#ifdef H5F_DEBUG - fprintf(stderr, "HDF5-DIAG: opening a split file\n"); -#endif - fullname[s - name] = '\0'; - f = H5F_open(H5F_LOW_SPLIT, fullname, flags, create_parms, access_parms); - HRETURN(f); - } - } - } - - /* - * If no file creation parameters are supplied then use defaults. + * If no file creation parameters or file access parameters are supplied + * then use defaults. */ - if (!create_parms) - create_parms = &H5F_create_dflt; + if (!create_parms) create_parms = &H5F_create_dflt; + if (!access_parms) access_parms = &H5F_access_dflt; /* * Does the file exist? If so, get the device and i-node values so we can @@ -659,112 +685,119 @@ H5F_open(const H5F_low_class_t *type, const char *name, uintn flags, * with hard or soft links) it doesn't work to compare files based only on * their full path name. */ - file_exists = H5F_low_access(type, name, F_OK, &search); + type = H5F_low_class (access_parms->driver); + assert (type); + file_exists = H5F_low_access(type, name, access_parms, F_OK, &search); /* * Open the low-level file (if necessary) and create an H5F_t struct that * points to an H5F_file_t struct. */ if (file_exists) { - if (flags & H5F_ACC_EXCL) { - HRETURN_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, - "file already exists - CREAT EXCL failed"); - } - if (!H5F_low_access(type, name, R_OK, NULL)) { - HRETURN_ERROR(H5E_FILE, H5E_READERROR, NULL, - "file is not readable"); - } - if ((flags & H5F_ACC_WRITE) && - !H5F_low_access(type, name, W_OK, NULL)) { - HRETURN_ERROR(H5E_FILE, H5E_WRITEERROR, NULL, - "file is not writable"); - } - if ((old = H5A_search(H5_FILE, H5F_compare_files, &search))) { - if (flags & H5F_ACC_TRUNC) { - HRETURN_ERROR(H5E_FILE, H5E_FILEOPEN, NULL, - "file already open - TRUNC failed"); - } - if ((flags & H5F_ACC_WRITE) && - 0 == (old->shared->flags & H5F_ACC_WRITE)) { - if (NULL == (fd = H5F_low_open(type, name, H5F_ACC_WRITE, NULL))) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "file cannot be reopened with write access"); - } - H5F_low_close(old->shared->lf); - old->shared->lf = fd; - old->shared->flags |= H5F_ACC_WRITE; - fd = NULL; /*so we don't close it during error */ - } - f = H5F_new(old->shared); - - } else if (flags & H5F_ACC_TRUNC) { - /* Truncate existing file */ - if (0 == (flags & H5F_ACC_WRITE)) { - HRETURN_ERROR(H5E_FILE, H5E_BADVALUE, NULL, - "can't truncate without write intent"); - } - fd = H5F_low_open(type, name, H5F_ACC_WRITE | H5F_ACC_TRUNC, NULL); - if (!fd) { - HRETURN_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, - "can't truncate file"); - } - f = H5F_new(NULL); - f->shared->key = search; - f->shared->flags = flags; - f->shared->lf = fd; - empty_file = TRUE; - - } else { - fd = H5F_low_open(type, name, (flags & H5F_ACC_WRITE), NULL); - if (!fd) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "cannot open existing file"); - } - f = H5F_new(NULL); - f->shared->key = search; - f->shared->flags = flags; - f->shared->lf = fd; - } + if (flags & H5F_ACC_EXCL) { + HRETURN_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, + "file already exists - CREAT EXCL failed"); + } + if (!H5F_low_access(type, name, access_parms, R_OK, NULL)) { + HRETURN_ERROR(H5E_FILE, H5E_READERROR, NULL, + "file is not readable"); + } + if ((flags & H5F_ACC_RDWR) && + !H5F_low_access(type, name, access_parms, W_OK, NULL)) { + HRETURN_ERROR(H5E_FILE, H5E_WRITEERROR, NULL, + "file is not writable"); + } + if ((old = H5A_search(H5_FILE, H5F_compare_files, &search))) { + if (flags & H5F_ACC_TRUNC) { + HRETURN_ERROR(H5E_FILE, H5E_FILEOPEN, NULL, + "file already open - TRUNC failed"); + } + if ((flags & H5F_ACC_RDWR) && + 0 == (old->shared->flags & H5F_ACC_RDWR)) { + if (NULL==(fd=H5F_low_open(type, name, access_parms, + H5F_ACC_RDWR, NULL))) { + HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "file cannot be reopened with write access"); + } + H5F_low_close(old->shared->lf, access_parms); + old->shared->lf = fd; + old->shared->flags |= H5F_ACC_RDWR; + fd = NULL; /*so we don't close it during error */ + } + f = H5F_new(old->shared); + + } else if (flags & H5F_ACC_TRUNC) { + /* Truncate existing file */ + if (0 == (flags & H5F_ACC_RDWR)) { + HRETURN_ERROR(H5E_FILE, H5E_BADVALUE, NULL, + "can't truncate without write intent"); + } + fd = H5F_low_open(type, name, access_parms, + H5F_ACC_RDWR | H5F_ACC_TRUNC, NULL); + if (!fd) { + HRETURN_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, + "can't truncate file"); + } + f = H5F_new(NULL); + f->shared->key = search; + f->shared->flags = flags; + f->shared->lf = fd; + empty_file = TRUE; + + } else { + fd = H5F_low_open(type, name, access_parms, + (flags & H5F_ACC_RDWR), NULL); + if (!fd) { + HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "cannot open existing file"); + } + f = H5F_new(NULL); + f->shared->key = search; + f->shared->flags = flags; + f->shared->lf = fd; + } } else if (flags & H5F_ACC_CREAT) { - if (0 == (flags & H5F_ACC_WRITE)) { - HRETURN_ERROR(H5E_FILE, H5E_BADVALUE, NULL, - "can't create file without write intent"); - } + if (0 == (flags & H5F_ACC_RDWR)) { + HRETURN_ERROR(H5E_FILE, H5E_BADVALUE, NULL, + "can't create file without write intent"); + } #ifdef HAVE_PARALLEL - /* ROMIO cannot handle file-open with EXCL Create due to racing problem */ - /* The first process creates the file which then fails all */ - /* other processes. Turn on TRUNC bit here. It does not matter */ - /* since the file does not exist at this point. */ - fd = H5F_low_open(type, name, - H5F_ACC_WRITE | H5F_ACC_CREAT | + /* + * ROMIO cannot handle file-open with EXCL Create due to racing + * problem. The first process creates the file which then fails all + * other processes. Turn on TRUNC bit here. It does not matter since + * the file does not exist at this point. + */ + fd = H5F_low_open(type, name, access_parms, + H5F_ACC_RDWR | H5F_ACC_CREAT | (flags & H5F_ACC_TRUNC), - &search); + &search); #else - fd = H5F_low_open(type, name, - H5F_ACC_WRITE | H5F_ACC_CREAT | + fd = H5F_low_open(type, name, access_parms, + H5F_ACC_RDWR | H5F_ACC_CREAT | (flags & H5F_ACC_EXCL) | (flags & H5F_ACC_TRUNC), - &search); + &search); #endif /*HAVE_PARALLEL*/ - if (!fd) { - HRETURN_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, - "can't create file"); - } - f = H5F_new(NULL); - f->shared->key = search; - f->shared->flags = flags; - f->shared->lf = fd; - empty_file = TRUE; + if (!fd) { + HRETURN_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, + "can't create file"); + } + f = H5F_new(NULL); + f->shared->key = search; + f->shared->flags = flags; + f->shared->lf = fd; + empty_file = TRUE; } else { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "file does not exist"); + HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "file does not exist"); } assert(f); /* * The intent at the top level file struct are not necessarily the same as - * the flags at the bottom. The top level describes how the file can be + * the flags at the bottom. The top level describes how the file can be * accessed through the HDF5 library. The bottom level describes how the * file can be accessed through the C library. */ @@ -772,11 +805,12 @@ H5F_open(const H5F_low_class_t *type, const char *name, uintn flags, f->name = H5MM_xstrdup(name); /* - * Update the file creation parameters with default values if this is the - * first time this file is opened. + * Update the file creation parameters and file access parameters with + * default values if this is the first time this file is opened. */ if (1 == f->shared->nrefs) { - f->shared->create_parms = *create_parms; + f->shared->create_parms = *create_parms; + f->shared->access_parms = *access_parms; } cp = &(f->shared->create_parms); @@ -784,131 +818,140 @@ H5F_open(const H5F_low_class_t *type, const char *name, uintn flags, * Read or write the file boot block. */ if (empty_file) { - /* - * For new files we must write the boot block. The boot block starts - * immediately after the user-defined header, which we have already - * insured is a proper size. The base address is set to the same thing - * as the boot block. - */ - H5F_addr_reset(&(f->shared->boot_addr)); - H5F_addr_inc(&(f->shared->boot_addr), - f->shared->create_parms.userblock_size); - f->shared->base_addr = f->shared->boot_addr; - - f->shared->consist_flags = 0x03; - if (H5F_flush(f, FALSE) < 0) { - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, - "can't write file boot block"); - } + /* + * For new files we must write the boot block. The boot block starts + * immediately after the user-defined header, which we have already + * insured is a proper size. The base address is set to the same thing + * as the boot block. + */ + H5F_addr_reset(&(f->shared->boot_addr)); + H5F_addr_inc(&(f->shared->boot_addr), + f->shared->create_parms.userblock_size); + f->shared->base_addr = f->shared->boot_addr; + + f->shared->consist_flags = 0x03; + if (H5F_flush(f, FALSE) < 0) { + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, + "can't write file boot block"); + } + } else if (1 == f->shared->nrefs) { - /* For existing files we must read the boot block. */ - if (H5F_locate_signature(f->shared->lf, &(f->shared->boot_addr)) < 0) { - HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, NULL, "can't find signature"); - } - if (H5F_low_read(f->shared->lf, &(f->shared->boot_addr), - fixed_size, buf) < 0) { - HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "can't read boot block"); - } - /* - * Decode the fixed size part of the boot block. For each of the - * version parameters, check that the library is able to handle that - * version. - */ - p = buf + H5F_SIGNATURE_LEN; /*already checked */ - - cp->bootblock_ver = *p++; - if (cp->bootblock_ver != HDF5_BOOTBLOCK_VERSION) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad boot block version number"); - } - cp->smallobject_ver = *p++; - if (cp->smallobject_ver != HDF5_SMALLOBJECT_VERSION) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad small object heap version number"); - } - cp->freespace_ver = *p++; - if (cp->freespace_ver != HDF5_FREESPACE_VERSION) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad free space version number"); - } - cp->objectdir_ver = *p++; - if (cp->objectdir_ver != HDF5_OBJECTDIR_VERSION) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad object dir version number"); - } - cp->sharedheader_ver = *p++; - if (cp->sharedheader_ver != HDF5_SHAREDHEADER_VERSION) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad shared header version number"); - } - cp->sizeof_addr = *p++; - if (cp->sizeof_addr != 2 && - cp->sizeof_addr != 4 && - cp->sizeof_addr != 8 && - cp->sizeof_addr != 16 && - cp->sizeof_addr != 32) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad address size"); - } - cp->sizeof_size = *p++; - if (cp->sizeof_size != 2 && - cp->sizeof_size != 4 && - cp->sizeof_size != 8 && - cp->sizeof_size != 16 && - cp->sizeof_size != 32) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad length size"); - } - /* Reserved byte */ - p++; - - UINT16DECODE(p, cp->sym_leaf_k); - if (cp->sym_leaf_k < 1) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad symbol table leaf node 1/2 rank"); - } - UINT16DECODE(p, cp->btree_k[H5B_SNODE_ID]); - if (cp->btree_k[H5B_SNODE_ID] < 1) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad symbol table internal node 1/2 rank"); - } - UINT32DECODE(p, f->shared->consist_flags); - /* nothing to check for consistency flags */ - - assert(p - buf == fixed_size); - - /* Read the variable length part of the boot block... */ - variable_size = H5F_SIZEOF_ADDR(f) + /*base address */ - H5F_SIZEOF_ADDR(f) + /*global small obj heap */ - H5F_SIZEOF_ADDR(f) + /*global free list addr */ - H5F_SIZEOF_ADDR(f) + /*logical file size */ - H5G_SIZEOF_ENTRY(f); - assert(variable_size <= sizeof buf); - addr1 = f->shared->boot_addr; - H5F_addr_inc(&addr1, fixed_size); - if (H5F_low_read(f->shared->lf, &addr1, variable_size, buf) < 0) { - HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, NULL, - "can't read boot block"); - } - p = buf; - H5F_addr_decode(f, &p, &(f->shared->base_addr)); - H5F_addr_decode(f, &p, &(f->shared->smallobj_addr)); - H5F_addr_decode(f, &p, &(f->shared->freespace_addr)); - H5F_addr_decode(f, &p, &(f->shared->hdf5_eof)); - if (H5G_ent_decode(f, &p, &root_ent) < 0) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "can't read root symbol entry"); - } - if (H5F_addr_defined(&(root_ent.header))) { - f->shared->root_ent = H5MM_xmalloc(sizeof(H5G_entry_t)); - *(f->shared->root_ent) = root_ent; - } - /* - * The userdefined data is the area of the file before the base - * address. - */ - f->shared->create_parms.userblock_size = f->shared->base_addr.offset; + /* For existing files we must read the boot block. */ + if (H5F_locate_signature(f->shared->lf, + &(f->shared->access_parms), + &(f->shared->boot_addr)) < 0) { + HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, NULL, "can't find signature"); + } + if (H5F_low_read(f->shared->lf, access_parms, &(f->shared->boot_addr), + fixed_size, buf) < 0) { + HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "can't read boot block"); + } + + /* + * Decode the fixed size part of the boot block. For each of the + * version parameters, check that the library is able to handle that + * version. + */ + p = buf + H5F_SIGNATURE_LEN; /*already checked */ + + cp->bootblock_ver = *p++; + if (cp->bootblock_ver != HDF5_BOOTBLOCK_VERSION) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "bad boot block version number"); + } + cp->smallobject_ver = *p++; + if (cp->smallobject_ver != HDF5_SMALLOBJECT_VERSION) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "bad small object heap version number"); + } + cp->freespace_ver = *p++; + if (cp->freespace_ver != HDF5_FREESPACE_VERSION) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "bad free space version number"); + } + cp->objectdir_ver = *p++; + if (cp->objectdir_ver != HDF5_OBJECTDIR_VERSION) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "bad object dir version number"); + } + cp->sharedheader_ver = *p++; + if (cp->sharedheader_ver != HDF5_SHAREDHEADER_VERSION) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "bad shared header version number"); + } + cp->sizeof_addr = *p++; + if (cp->sizeof_addr != 2 && + cp->sizeof_addr != 4 && + cp->sizeof_addr != 8 && + cp->sizeof_addr != 16 && + cp->sizeof_addr != 32) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "bad address size"); + } + cp->sizeof_size = *p++; + if (cp->sizeof_size != 2 && + cp->sizeof_size != 4 && + cp->sizeof_size != 8 && + cp->sizeof_size != 16 && + cp->sizeof_size != 32) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "bad length size"); + } + + /* Reserved byte */ + p++; + + UINT16DECODE(p, cp->sym_leaf_k); + if (cp->sym_leaf_k < 1) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "bad symbol table leaf node 1/2 rank"); + } + UINT16DECODE(p, cp->btree_k[H5B_SNODE_ID]); + if (cp->btree_k[H5B_SNODE_ID] < 1) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "bad symbol table internal node 1/2 rank"); + } + UINT32DECODE(p, f->shared->consist_flags); + + /* nothing to check for consistency flags */ + + assert(p - buf == fixed_size); + + /* Read the variable length part of the boot block... */ + variable_size = H5F_SIZEOF_ADDR(f) + /*base address */ + H5F_SIZEOF_ADDR(f) + /*global small obj heap */ + H5F_SIZEOF_ADDR(f) + /*global free list addr */ + H5F_SIZEOF_ADDR(f) + /*logical file size */ + H5G_SIZEOF_ENTRY(f); + assert(variable_size <= sizeof buf); + addr1 = f->shared->boot_addr; + H5F_addr_inc(&addr1, fixed_size); + if (H5F_low_read(f->shared->lf, access_parms, &addr1, variable_size, + buf) < 0) { + HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, NULL, + "can't read boot block"); + } + p = buf; + H5F_addr_decode(f, &p, &(f->shared->base_addr)); + H5F_addr_decode(f, &p, &(f->shared->smallobj_addr)); + H5F_addr_decode(f, &p, &(f->shared->freespace_addr)); + H5F_addr_decode(f, &p, &(f->shared->hdf5_eof)); + if (H5G_ent_decode(f, &p, &root_ent) < 0) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "can't read root symbol entry"); + } + if (H5F_addr_defined(&(root_ent.header))) { + f->shared->root_ent = H5MM_xmalloc(sizeof(H5G_entry_t)); + *(f->shared->root_ent) = root_ent; + } + + /* + * The userdefined data is the area of the file before the base + * address. + */ + f->shared->create_parms.userblock_size = f->shared->base_addr.offset; } + /* * What is the current size of the file? The max_addr field is a relative * address while H5F_low_size() returns an absolute address. @@ -917,265 +960,243 @@ H5F_open(const H5F_low_class_t *type, const char *name, uintn flags, addr2 = f->shared->hdf5_eof; H5F_addr_add(&addr2, &(f->shared->base_addr)); if (H5F_addr_lt(&addr1, &addr2)) { - /* - * Truncated file? This might happen if one tries to open the first - * member of a file family. - */ - HGOTO_ERROR(H5E_FILE, H5E_TRUNCATED, NULL, "truncated file"); + /* + * Truncated file? This might happen if one tries to open the first + * member of a file family. + */ + HGOTO_ERROR(H5E_FILE, H5E_TRUNCATED, NULL, "truncated file"); + } else if (H5F_addr_gt(&addr1, &addr2)) { - /* - * The file is larger than the hdf5 data. It either has extra junk at - * the end, or a wrapper. In either case, make the file think it's - * shorter so when we allocate memory from the file for hdf5 it's - * allocated immediately after the end of the previous hdf5 data. This - * will cause internal wrappers to be overwritten if they follow the - * hdf5 data. - */ + /* + * The file is larger than the hdf5 data. It either has extra junk at + * the end, or a wrapper. In either case, make the file think it's + * shorter so when we allocate memory from the file for hdf5 it's + * allocated immediately after the end of the previous hdf5 data. This + * will cause internal wrappers to be overwritten if they follow the + * hdf5 data. + */ #ifdef H5F_DEBUG - fprintf(stderr, "HDF5-DIAG: resetting EOF from "); - H5F_addr_print(stderr, &addr1); - fprintf(stderr, " to "); - H5F_addr_print(stderr, &addr2); - fprintf(stderr, " (abs)\n"); + fprintf(stderr, "HDF5-DIAG: resetting EOF from "); + H5F_addr_print(stderr, &addr1); + fprintf(stderr, " to "); + H5F_addr_print(stderr, &addr2); + fprintf(stderr, " (abs)\n"); #endif - H5F_low_seteof(f->shared->lf, &addr2); + H5F_low_seteof(f->shared->lf, &addr2); } + /* Success! */ ret_value = f; done: if (!ret_value) { - if (f) - H5F_dest(f); - H5F_low_close(fd); + if (f) H5F_dest(f); + H5F_low_close(fd, access_parms); } FUNC_LEAVE(ret_value); } -/*-------------------------------------------------------------------------- - NAME - H5Fcreate - - PURPOSE - Create a new HDF5 file. - - USAGE - int32 H5Fcreate(filename, flags, create_temp, access_temp) - const char *filename; IN: Name of the file to create - uintn flags; IN: Flags to indicate various options. - hid_t create_temp; IN: File-creation template ID - hid_t access_temp; IN: File-access template ID - - ERRORS - ARGS BADVALUE Invalid file name. - ARGS BADVALUE Invalid flags. - ATOM BADATOM Can't unatomize template. - ATOM CANTREGISTER Can't atomize file. - FILE CANTOPENFILE Can't create file. - - RETURNS - Returns file ID on success, FAIL on failure - - DESCRIPTION - This is the primary function for creating HDF5 files . The flags - parameter determines whether an existing file will be overwritten or not. - All newly created files are opened for both reading and writing. All flags - may be combined with the "||" (logical OR operator) to change the behavior - of the file open call. - The flags currently defined: - H5ACC_OVERWRITE - Truncate file, if it already exists. The file - will be truncated, erasing all data previously stored in the - file. - The more complex behaviors of a file's creation and access are - controlled through the file-creation and file-access templates. The value - of 0 for a template value indicates that the library should use the default - values for the appropriate template. (Documented in the template module). - [Access templates are currently unused in this routine, although they will - be implemented in the future] - - MODIFICATIONS: - Robb Matzke, 18 Jul 1997 - File struct creation and destruction is through H5F_new() H5F_dest(). - Writing the root symbol table entry is done with H5G_encode(). - - Robb Matzke, 29 Aug 1997 - Moved creation of the boot block to H5F_flush(). - - Robb Matzke, 23 Sep 1997 - Most of the work is now done by H5F_open() since H5Fcreate() and H5Fopen() - originally contained almost identical code. ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Fcreate + * + * Purpose: This is the primary function for creating HDF5 files . The + * flags parameter determines whether an existing file will be + * overwritten or not. All newly created files are opened for + * both reading and writing. All flags may be combined with the + * bit-wise OR operator (`|') to change the behavior of the file + * create call. + * + * The more complex behaviors of a file's creation and access + * are controlled through the file-creation and file-access + * property lists. The value of H5C_DEFAULT for a template + * value indicates that the library should use the default + * values for the appropriate template. + * + * See also: H5Fpublic.h for the list of supported flags. H5Cpublic.h for + * the list of file creation and file access properties. + * + * Return: Success: A file ID + * + * Failure: FAIL + * + * Programmer: Unknown + * + * Modifications: + * + * Robb Matzke, 18 Jul 1997 + * File struct creation and destruction is through H5F_new() H5F_dest(). + * Writing the root symbol table entry is done with H5G_encode(). + * + * Robb Matzke, 29 Aug 1997 + * Moved creation of the boot block to H5F_flush(). + * + * Robb Matzke, 23 Sep 1997 + * Most of the work is now done by H5F_open() since H5Fcreate() and + * H5Fopen() originally contained almost identical code. + * + * Robb Matzke, 18 Feb 1998 + * Better error checking for the creation and access property lists. It + * used to be possible to swap the two and core the library. Also, zero + * is no longer valid as a default property list; one must use + * H5C_DEFAULT instead. + * + *------------------------------------------------------------------------- + */ hid_t -H5Fcreate(const char *filename, uintn flags, hid_t create_temp, - hid_t access_temp) +H5Fcreate(const char *filename, uintn flags, hid_t create_id, + hid_t access_id) { - H5F_t *new_file = NULL; /* file struct for new file */ - const H5F_create_t *create_parms; /* pointer to the parameters to - * use when creating the file - */ - const H5F_access_t *access_parms; /* pointer to the file access - * parameters to use when creating - * the file - */ - const H5F_low_class_t *type; /* File type */ - hid_t ret_value = FAIL; + + H5F_t *new_file = NULL; /* file struct for new file */ + const H5F_create_t *create_parms; /* pointer to the parameters to + * use when creating the file + */ + const H5F_access_t *access_parms; /* pointer to the file access + * parameters to use when + * creating the file + */ + hid_t ret_value = FAIL; FUNC_ENTER(H5Fcreate, FAIL); /* Check/fix arguments */ - if (!filename || !*filename) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name"); - if (flags & ~H5ACC_OVERWRITE) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags"); - flags = (H5F_ACC_WRITE | H5F_ACC_CREAT) | - (H5ACC_OVERWRITE == flags ? H5F_ACC_TRUNC : H5F_ACC_EXCL); - - if (create_temp <= 0) { - create_parms = &H5F_create_dflt; - } else if (NULL == (create_parms = H5A_object(create_temp))) { - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't unatomize template"); + if (!filename || !*filename) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name"); } - if (access_temp <= 0) { - access_parms = &H5F_access_dflt; - } else if (NULL == (access_parms = H5A_object(access_temp))) { - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't unatomize template"); + if (flags & ~(H5F_ACC_EXCL|H5F_ACC_TRUNC)) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags"); } - /* figure out what kind of file I/O to use. */ - /* Currently, MPIO is the only alternative than default I/O */ - switch (access_parms->access_mode){ - case H5ACC_DEFAULT: - type = H5F_LOW_DFLT; - break; -#ifdef HAVE_PARALLEL - case H5ACC_INDEPENDENT: - type = H5F_LOW_MPIO; - break; - case H5ACC_COLLECTIVE: - /* not implemented yet */ - /* type = H5F_LOW_MPIO; */ - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid file access mode"); -#endif - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid file access mode"); + if ((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_EXCL)) { + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "mutually exclusive flags for file creation"); } - + if (H5C_DEFAULT==create_id) { + create_parms = &H5F_create_dflt; + } else if (H5C_FILE_CREATE!=H5Cget_class (create_id) || + NULL == (create_parms = H5A_object(create_id))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file creation property list"); + } + if (H5C_DEFAULT==access_id) { + access_parms = &H5F_access_dflt; + } else if (H5C_FILE_ACCESS!=H5Cget_class (access_id) || + NULL == (access_parms = H5A_object(access_id))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + + /* + * Adjust bit flags by turning on the creation bit and making sure that + * the EXCL or TRUNC bit is set. All newly-created files are opened for + * reading and writing. + */ + if (0==(flags & (H5F_ACC_EXCL|H5F_ACC_TRUNC))) { + flags |= H5F_ACC_EXCL; /*default*/ + } + flags |= H5F_ACC_RDWR | H5F_ACC_CREAT; + /* * Create a new file or truncate an existing file. */ - if (NULL == (new_file = H5F_open(type, filename, flags, - create_parms, access_parms))) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't create file"); + if (NULL == (new_file = H5F_open(filename, flags, create_parms, + access_parms))) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file"); } + /* Get an atom for the file */ - if ((ret_value = H5A_register(H5_FILE, new_file)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't atomize file"); + if ((ret_value = H5A_register(H5_FILE, new_file)) < 0) { + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to atomize file"); + } done: if (ret_value < 0 && new_file) { - /* Error condition cleanup */ - H5F_close(new_file); + /* Error condition cleanup */ + H5F_close(new_file); } - /* Normal function cleanup */ FUNC_LEAVE(ret_value); } -/*-------------------------------------------------------------------------- - NAME - H5Fopen - - PURPOSE - Open an existing HDF5 file. - - USAGE - hid_t H5Fopen(filename, flags, access_temp) - const char *filename; IN: Name of the file to create - uintn flags; IN: Flags to indicate various options. - hid_t access_temp; IN: File-access template - - ERRORS - ARGS BADRANGE Invalid file name. - ATOM BADATOM Can't unatomize template. - ATOM CANTREGISTER Can't atomize file. - FILE CANTOPENFILE Cant open file. - - RETURNS - Returns file ID on success, FAIL on failure - - DESCRIPTION - This is the primary function for accessing existing HDF5 files. The - flags parameter determines whether writing to an existing file will be - allowed or not. All flags may be combined with the "||" (logical OR - operator) to change the behavior of the file open call. - The flags currently defined: - H5ACC_WRITE - Allow writing to the file. - The more complex behaviors of a file's access are controlled through - the file-access template. - - MODIFICATIONS: - Robb Matzke, 18 Jul 1997 - File struct creation and destruction is through H5F_new() H5F_dest(). - Reading the root symbol table entry is done with H5G_decode(). - - Robb Matzke, 23 Sep 1997 - Most of the work is now done by H5F_open() since H5Fcreate() and H5Fopen() - originally contained almost identical code. ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Fopen + * + * Purpose: This is the primary function for accessing existing HDF5 + * files. The FLAGS argument determines whether writing to an + * existing file will be allowed or not. All flags may be + * combined with the bit-wise OR operator (`|') to change the + * behavior of the file open call. The more complex behaviors + * of a file's access are controlled through the file-access + * property list. + * + * See Also: H5Fpublic.h for a list of possible values for FLAGS. + * + * Return: Success: A file ID + * + * Failure: FAIL + * + * Programmer: Unknown + * + * Modifications: + * + * Robb Matzke, 18 Jul 1997 + * File struct creation and destruction is through H5F_new() H5F_dest(). + * Reading the root symbol table entry is done with H5G_decode(). + * + * Robb Matzke, 23 Sep 1997 + * Most of the work is now done by H5F_open() since H5Fcreate() and + * H5Fopen() originally contained almost identical code. + * + * Robb Matzke, 18 Feb 1998 + * Added better error checking for the flags and the file access + * property list. It used to be possible to make the library dump core + * by passing an object ID that was not a file access property list. + * + *------------------------------------------------------------------------- + */ hid_t -H5Fopen(const char *filename, uintn flags, hid_t access_temp) +H5Fopen(const char *filename, uintn flags, hid_t access_id) { - H5F_t *new_file = NULL; /* file struct for new file */ - const H5F_access_t *access_parms; /* pointer to the file access - * parameters to use when creating - * the file - */ - const H5F_low_class_t *type; /* File type */ - hid_t ret_value = FAIL; + H5F_t *new_file = NULL; /* file struct for new file */ + const H5F_access_t *access_parms; /* pointer to the file access + * parameters to use when + * creating the file + */ + hid_t ret_value = FAIL; FUNC_ENTER(H5Fopen, FAIL); /* Check/fix arguments. */ - if (!filename || !*filename) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid file name"); - flags = flags & H5ACC_WRITE ? H5F_ACC_WRITE : 0; - - if (access_temp <= 0) { - access_parms = &H5F_access_dflt; - } else if (NULL == (access_parms = H5A_object(access_temp))) { - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't unatomize template"); + if (!filename || !*filename) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name"); } - /* figure out what kind of file I/O to use. */ - /* Currently, MPIO is the only alternative than default I/O */ - switch (access_parms->access_mode){ - case H5ACC_DEFAULT: - type = H5F_LOW_DFLT; - break; -#ifdef HAVE_PARALLEL - case H5ACC_INDEPENDENT: - type = H5F_LOW_MPIO; - break; - case H5ACC_COLLECTIVE: - /* not implemented yet */ - /* type = H5F_LOW_MPIO; */ - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid file access mode"); -#endif - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid file access mode"); + if ((flags & ~H5F_ACC_PUBLIC_FLAGS) || + (flags & H5F_ACC_TRUNC) || (flags & H5F_ACC_EXCL)) { + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags"); + } + if (H5C_DEFAULT==access_id) { + access_parms = &H5F_access_dflt; + } else if (H5C_FILE_ACCESS!=H5Cget_class (access_id) || + NULL == (access_parms = H5A_object(access_id))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); } /* Open the file */ - if (NULL == (new_file = H5F_open(type, filename, flags, NULL, access_parms))) { - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "cant open file"); + if (NULL==(new_file=H5F_open(filename, flags, NULL, access_parms))) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "cant open file"); } + /* Get an atom for the file */ - if ((ret_value = H5A_register(H5_FILE, new_file)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't atomize file"); + if ((ret_value = H5A_register(H5_FILE, new_file)) < 0) { + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't atomize file"); + } - done: + done: if (ret_value < 0 && new_file) { - H5F_close(new_file); + H5F_close(new_file); } /* Normal function cleanup */ @@ -1183,23 +1204,23 @@ H5Fopen(const char *filename, uintn flags, hid_t access_temp) } /*------------------------------------------------------------------------- - * Function: H5F_flush + * Function: H5F_flush * - * Purpose: Flushes (and optionally invalidates) cached data plus the - * file boot block. If the logical file size field is zero - * then it is updated to be the length of the boot block. + * Purpose: Flushes (and optionally invalidates) cached data plus the + * file boot block. If the logical file size field is zero + * then it is updated to be the length of the boot block. * * Errors: - * CACHE CANTFLUSH Can't flush cache. - * IO WRITEERROR Can't write header. + * CACHE CANTFLUSH Can't flush cache. + * IO WRITEERROR Can't write header. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 29 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 29 1997 * * Modifications: * @@ -1208,23 +1229,24 @@ H5Fopen(const char *filename, uintn flags, hid_t access_temp) static herr_t H5F_flush(H5F_t *f, hbool_t invalidate) { - uint8 buf[2048], *p = buf; + uint8 buf[2048], *p = buf; FUNC_ENTER(H5F_flush, FAIL); /* - * Nothing to do if the file is read only. This determination is made at + * Nothing to do if the file is read only. This determination is made at * the shared open(2) flags level, implying that opening a file twice, * once for read-only and once for read-write, and then calling * H5F_flush() with the read-only handle, still causes data to be flushed. */ - if (0 == (H5F_ACC_WRITE & f->shared->flags)) - HRETURN(SUCCEED); + if (0 == (H5F_ACC_RDWR & f->shared->flags)) + HRETURN(SUCCEED); /* flush (and invalidate) the entire cache */ if (H5AC_flush(f, NULL, 0, invalidate) < 0) { - HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't flush cache"); + HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't flush cache"); } + /* encode the file boot block */ HDmemcpy(p, H5F_SIGNATURE, H5F_SIGNATURE_LEN); p += H5F_SIGNATURE_LEN; @@ -1238,7 +1260,7 @@ H5F_flush(H5F_t *f, hbool_t invalidate) *p++ = (uint8)H5F_SIZEOF_ADDR(f); assert (H5F_SIZEOF_SIZE(f)<=255); *p++ = (uint8)H5F_SIZEOF_SIZE(f); - *p++ = 0; /*reserved */ + *p++ = 0; /*reserved */ UINT16ENCODE(p, f->shared->create_parms.sym_leaf_k); UINT16ENCODE(p, f->shared->create_parms.btree_k[H5B_SNODE_ID]); UINT32ENCODE(p, f->shared->consist_flags); @@ -1250,32 +1272,35 @@ H5F_flush(H5F_t *f, hbool_t invalidate) /* update file length if necessary */ if (!H5F_addr_defined(&(f->shared->hdf5_eof))) { - H5F_addr_reset(&(f->shared->hdf5_eof)); - H5F_addr_inc(&(f->shared->hdf5_eof), p - buf); - H5F_low_seteof(f->shared->lf, &(f->shared->hdf5_eof)); + H5F_addr_reset(&(f->shared->hdf5_eof)); + H5F_addr_inc(&(f->shared->hdf5_eof), p - buf); + H5F_low_seteof(f->shared->lf, &(f->shared->hdf5_eof)); } + /* write the boot block to disk */ - if (H5F_low_write(f->shared->lf, &(f->shared->boot_addr), p - buf, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't write header"); + if (H5F_low_write(f->shared->lf, &(f->shared->access_parms), + &(f->shared->boot_addr), p-buf, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't write header"); } + /* Flush file buffers to disk */ - if (H5F_low_flush(f->shared->lf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed"); + if (H5F_low_flush(f->shared->lf, &(f->shared->access_parms)) < 0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed"); } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5F_close + * Function: H5F_close * - * Purpose: Closes an open HDF5 file. + * Purpose: Closes an open HDF5 file. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, September 23, 1997 + * Programmer: Robb Matzke + * Tuesday, September 23, 1997 * * Modifications: * @@ -1287,13 +1312,13 @@ H5F_close(H5F_t *f) FUNC_ENTER(H5F_close, FAIL); /* Close all current working groups */ - while (H5G_pop(f) >= 0) /*void */ - ; + while (H5G_pop(f) >= 0) /*void*/; /* Flush the boot block and caches */ if (H5F_flush(f, TRUE) < 0) { - HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't flush cache"); + HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "can't flush cache"); } + /* * If object headers are still open then delay deletion of resources until * they have all been closed. The file is in a consistent state now, so @@ -1301,25 +1326,25 @@ H5F_close(H5F_t *f) */ if (f->nopen > 0) { #ifndef NDEBUG - fprintf(stderr, "HDF5-DIAG: H5F_close: %d object header%s still " - "open (file close will complete when %s closed)\n", - f->nopen, - 1 == f->nopen ? " is" : "s are", - 1 == f->nopen ? "that header is" : "those headers are"); + fprintf(stderr, "HDF5-DIAG: H5F_close: %d object header%s still " + "open (file close will complete when %s closed)\n", + f->nopen, + 1 == f->nopen ? " is" : "s are", + 1 == f->nopen ? "that header is" : "those headers are"); #endif - f->close_pending = TRUE; - HRETURN(SUCCEED); + f->close_pending = TRUE; + HRETURN(SUCCEED); } else if (f->close_pending) { #ifndef NDEBUG - fprintf(stderr, "HDF5-DIAG: H5F_close: operation completed\n"); + fprintf(stderr, "HDF5-DIAG: H5F_close: operation completed\n"); #endif } + /* Dump debugging info */ - if (f->intent & H5F_ACC_DEBUG) - H5AC_debug(f); + if (f->intent & H5F_ACC_DEBUG) H5AC_debug(f); /* Close files and release resources */ - H5F_low_close(f->shared->lf); + H5F_low_close(f->shared->lf, &(f->shared->access_parms)); f = H5F_dest(f); FUNC_LEAVE(SUCCEED); @@ -1335,19 +1360,19 @@ H5F_close(H5F_t *f) USAGE herr_t H5Fclose(fid) - int32 fid; IN: File ID of file to close + int32 fid; IN: File ID of file to close ERRORS - ARGS BADTYPE Not a file atom. - ATOM BADATOM Can't remove atom. - ATOM BADATOM Can't unatomize file. - CACHE CANTFLUSH Can't flush cache. + ARGS BADTYPE Not a file atom. + ATOM BADATOM Can't remove atom. + ATOM BADATOM Can't unatomize file. + CACHE CANTFLUSH Can't flush cache. RETURNS SUCCEED/FAIL DESCRIPTION - This function terminates access to an HDF5 file. If this is the last + This function terminates access to an HDF5 file. If this is the last file ID open for a file and if access IDs are still in use, this function will fail. @@ -1362,45 +1387,48 @@ H5F_close(H5F_t *f) herr_t H5Fclose(hid_t fid) { - H5F_t *file = NULL; /* file struct for file to close */ - herr_t ret_value = SUCCEED; + H5F_t *file = NULL; /* file struct for file to close */ + herr_t ret_value = SUCCEED; FUNC_ENTER(H5Fclose, FAIL); /* Check/fix arguments. */ - if (H5_FILE != H5A_group(fid)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file atom"); - if (NULL == (file = H5A_object(fid))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't unatomize file"); + if (H5_FILE != H5A_group(fid)) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file atom"); + } + if (NULL == (file = H5A_object(fid))) { + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't unatomize file"); + } /* Close the file */ ret_value = H5F_close(file); /* Remove the file atom */ if (NULL == H5A_remove(fid)) { - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't remove atom"); + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't remove atom"); } - done: + + done: FUNC_LEAVE(ret_value < 0 ? FAIL : SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5F_block_read + * Function: H5F_block_read * - * Purpose: Reads some data from a file/server/etc into a buffer. - * The data is contiguous. The address is relative to the base - * address for the file. + * Purpose: Reads some data from a file/server/etc into a buffer. + * The data is contiguous. The address is relative to the base + * address for the file. * * Errors: - * IO READERROR Low-level read failed. + * IO READERROR Low-level read failed. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 10 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 10 1997 * * Modifications: * @@ -1409,42 +1437,43 @@ H5Fclose(hid_t fid) herr_t H5F_block_read(H5F_t *f, const haddr_t *addr, size_t size, void *buf) { - haddr_t abs_addr; + haddr_t abs_addr; FUNC_ENTER(H5F_block_read, FAIL); if (0 == size) - return 0; + return 0; /* convert the relative address to an absolute address */ abs_addr = f->shared->base_addr; H5F_addr_add(&abs_addr, addr); /* Read the data */ - if (H5F_low_read(f->shared->lf, &abs_addr, size, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "low-level read failed"); + if (H5F_low_read(f->shared->lf, &(f->shared->access_parms), + &abs_addr, size, buf) < 0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "low-level read failed"); } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5F_block_write + * Function: H5F_block_write * - * Purpose: Writes some data from memory to a file/server/etc. The - * data is contiguous. The address is relative to the base - * address. + * Purpose: Writes some data from memory to a file/server/etc. The + * data is contiguous. The address is relative to the base + * address. * * Errors: - * IO WRITEERROR Low-level write failed. - * IO WRITEERROR No write intent. + * IO WRITEERROR Low-level write failed. + * IO WRITEERROR No write intent. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 10 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 10 1997 * * Modifications: * @@ -1453,43 +1482,46 @@ H5F_block_read(H5F_t *f, const haddr_t *addr, size_t size, void *buf) herr_t H5F_block_write(H5F_t *f, const haddr_t *addr, size_t size, const void *buf) { - haddr_t abs_addr; + haddr_t abs_addr; FUNC_ENTER(H5F_block_write, FAIL); if (0 == size) - return 0; + return 0; - if (0 == (f->intent & H5F_ACC_WRITE)) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "no write intent"); + if (0 == (f->intent & H5F_ACC_RDWR)) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "no write intent"); } + /* Convert the relative address to an absolute address */ abs_addr = f->shared->base_addr; H5F_addr_add(&abs_addr, addr); /* Write the data */ - if (H5F_low_write(f->shared->lf, &abs_addr, size, buf)) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low-level write failed"); + if (H5F_low_write(f->shared->lf, &(f->shared->access_parms), + &abs_addr, size, buf)) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low-level write failed"); } + FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5F_debug + * Function: H5F_debug * - * Purpose: Prints a file header to the specified stream. Each line - * is indented and the field name occupies the specified width - * number of characters. + * Purpose: Prints a file header to the specified stream. Each line + * is indented and the field name occupies the specified width + * number of characters. * * Errors: * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 1 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 1 1997 * * Modifications: * @@ -1497,7 +1529,7 @@ H5F_block_write(H5F_t *f, const haddr_t *addr, size_t size, const void *buf) */ herr_t H5F_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, - intn fwidth) + intn fwidth) { FUNC_ENTER(H5F_debug, FAIL); @@ -1512,80 +1544,80 @@ H5F_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, fprintf(stream, "%*sFile Boot Block...\n", indent, ""); fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, - "File name:", - f->name); + "File name:", + f->name); fprintf(stream, "%*s%-*s 0x%08x\n", indent, "", fwidth, - "Flags", - (unsigned) (f->shared->flags)); + "Flags", + (unsigned) (f->shared->flags)); fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Reference count:", - (unsigned) (f->shared->nrefs)); + "Reference count:", + (unsigned) (f->shared->nrefs)); fprintf(stream, "%*s%-*s 0x%08lx\n", indent, "", fwidth, - "Consistency flags:", - (unsigned long) (f->shared->consist_flags)); + "Consistency flags:", + (unsigned long) (f->shared->consist_flags)); fprintf(stream, "%*s%-*s ", indent, "", fwidth, - "Address of boot block:"); + "Address of boot block:"); H5F_addr_print(stream, &(f->shared->boot_addr)); fprintf(stream, " (abs)\n"); fprintf(stream, "%*s%-*s ", indent, "", fwidth, - "Base address:"); + "Base address:"); H5F_addr_print(stream, &(f->shared->base_addr)); fprintf(stream, " (abs)\n"); fprintf(stream, "%*s%-*s ", indent, "", fwidth, - "Small object heap address:"); + "Small object heap address:"); H5F_addr_print(stream, &(f->shared->smallobj_addr)); fprintf(stream, " (rel)\n"); fprintf(stream, "%*s%-*s ", indent, "", fwidth, - "Free list address:"); + "Free list address:"); H5F_addr_print(stream, &(f->shared->freespace_addr)); fprintf(stream, " (rel)\n"); fprintf(stream, "%*s%-*s ", indent, "", fwidth, - "Total size of hdf5 data:"); + "Total size of hdf5 data:"); H5F_addr_print(stream, &(f->shared->hdf5_eof)); fprintf(stream, " bytes\n"); fprintf(stream, "%*s%-*s %lu bytes\n", indent, "", fwidth, - "Size of user block:", - (unsigned long) (f->shared->create_parms.userblock_size)); + "Size of user block:", + (unsigned long) (f->shared->create_parms.userblock_size)); fprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth, - "Size of file size_t type:", - (unsigned) (f->shared->create_parms.sizeof_size)); + "Size of file size_t type:", + (unsigned) (f->shared->create_parms.sizeof_size)); fprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth, - "Size of file haddr_t type:", - (unsigned) (f->shared->create_parms.sizeof_addr)); + "Size of file haddr_t type:", + (unsigned) (f->shared->create_parms.sizeof_addr)); fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Symbol table leaf node 1/2 rank:", - (unsigned) (f->shared->create_parms.sym_leaf_k)); + "Symbol table leaf node 1/2 rank:", + (unsigned) (f->shared->create_parms.sym_leaf_k)); fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Symbol table internal node 1/2 rank:", - (unsigned) (f->shared->create_parms.btree_k[H5B_SNODE_ID])); + "Symbol table internal node 1/2 rank:", + (unsigned) (f->shared->create_parms.btree_k[H5B_SNODE_ID])); fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Boot block version number:", - (unsigned) (f->shared->create_parms.bootblock_ver)); + "Boot block version number:", + (unsigned) (f->shared->create_parms.bootblock_ver)); fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Small object heap version number:", - (unsigned) (f->shared->create_parms.smallobject_ver)); + "Small object heap version number:", + (unsigned) (f->shared->create_parms.smallobject_ver)); fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Free list version number:", - (unsigned) (f->shared->create_parms.freespace_ver)); + "Free list version number:", + (unsigned) (f->shared->create_parms.freespace_ver)); fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Object directory version number:", - (unsigned) (f->shared->create_parms.objectdir_ver)); + "Object directory version number:", + (unsigned) (f->shared->create_parms.objectdir_ver)); fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Shared header version number:", - (unsigned) (f->shared->create_parms.sharedheader_ver)); + "Shared header version number:", + (unsigned) (f->shared->create_parms.sharedheader_ver)); fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, - "Root symbol table entry:", - f->shared->root_ent ? "" : "(none)"); + "Root symbol table entry:", + f->shared->root_ent ? "" : "(none)"); if (f->shared->root_ent) { - H5G_ent_debug(f, f->shared->root_ent, stream, - indent + 3, MAX(0, fwidth - 3)); + H5G_ent_debug(f, f->shared->root_ent, stream, + indent + 3, MAX(0, fwidth - 3)); } FUNC_LEAVE(SUCCEED); } |