summaryrefslogtreecommitdiffstats
path: root/src/H5F.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5F.c')
-rw-r--r--src/H5F.c1848
1 files changed, 940 insertions, 908 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 5561c40..6e639c3 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -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);
}