summaryrefslogtreecommitdiffstats
path: root/src/H5D.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5D.c')
-rw-r--r--src/H5D.c1482
1 files changed, 835 insertions, 647 deletions
diff --git a/src/H5D.c b/src/H5D.c
index 0b99e86..73f4933 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1,13 +1,13 @@
/****************************************************************************
-* 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. *
+* *
****************************************************************************/
#ifdef RCSID
@@ -16,52 +16,51 @@ static char RcsId[] = "@(#)$Revision$";
/* $Id$ */
-/*LINTLIBRARY */
-/*+
- FILE
- H5D.c
- HDF5 Dataset routines
-
- EXPORTED ROUTINES
- H5Dcreate -- Create a dataset
- H5Drelease -- Release access to a dataset
-
- LIBRARY-SCOPED ROUTINES
-
- LOCAL ROUTINES
- H5P_init_interface -- initialize the interface
- + */
-
-#include <H5private.h> /* Generic Functions */
-#include <H5Aprivate.h> /* Atoms */
-#include <H5Dprivate.h> /* Dataset functions */
-#include <H5Eprivate.h> /* Error handling */
-#include <H5Gprivate.h> /* Group headers */
-#include <H5Mprivate.h> /* Meta data */
-#include <H5MFprivate.h> /* File space allocation header */
-#include <H5MMprivate.h> /* Memory management */
-#include <H5Mprivate.h> /* Meta-Object API */
-#include <H5Oprivate.h> /* Object headers */
+
+#include <H5private.h> /* Generic Functions */
+#include <H5Aprivate.h> /* Atoms */
+#include <H5ACprivate.h> /* Cache */
+#include <H5Cprivate.h> /* Templates */
+#include <H5Dprivate.h> /* Dataset functions */
+#include <H5Eprivate.h> /* Error handling */
+#include <H5Gprivate.h> /* Group headers */
+#include <H5Mprivate.h> /* Meta data */
+#include <H5MFprivate.h> /* File space allocation header */
+#include <H5MMprivate.h> /* Memory management */
+#include <H5Mprivate.h> /* Meta-Object API */
+#include <H5Oprivate.h> /* Object headers */
#define PABLO_MASK H5D_mask
/*
* A dataset is the following struct.
*/
-typedef struct H5D_t {
- H5F_t *file; /* File store for this object */
- H5G_entry_t *ent; /* Cached object header stuff */
- hid_t tid; /* Datatype ID of this dataset */
- hid_t sid; /* Dataspace ID of this dataset */
- haddr_t data_addr; /* Data storage address */
- hbool_t dirty; /* Header messages not updated yet */
-} H5D_t;
-
-/*--------------------- Locally scoped variables -----------------------------*/
-
-/* Whether we've installed the library termination function yet for this interface */
-static intn interface_initialize_g = FALSE;
+struct H5D_t {
+ H5F_t *file; /* File store for this object */
+ H5G_entry_t *ent; /* Cached object header stuff */
+ H5T_t *type; /* Datatype of this dataset */
+ H5P_t *space; /* Dataspace of this dataset */
+ H5D_create_t create_parms; /* Creation parameters */
+ haddr_t data_addr; /* Raw data storage address */
+};
+
+/* Default dataset creation template */
+const H5D_create_t H5D_create_dflt = {
+ H5D_CONTIGUOUS, /* Layout */
+};
+
+/* Default dataset transfer template */
+const H5D_xfer_t H5D_xfer_dflt = {
+ 0, /* Place holder - remove this later */
+};
+
+
+/* Interface initialization? */
+static hbool_t interface_initialize_g = FALSE;
+#define INTERFACE_INIT H5D_init_interface
static herr_t H5D_init_interface(void);
+static void H5D_term_interface (void);
+
/*--------------------------------------------------------------------------
NAME
@@ -75,21 +74,21 @@ DESCRIPTION
Initializes any interface-specific data or routines.
--------------------------------------------------------------------------*/
-static herr_t H5D_init_interface(void)
+static herr_t
+H5D_init_interface (void)
{
- herr_t ret_value = SUCCEED;
- FUNC_ENTER (H5D_init_interface, NULL, FAIL);
-
- /* Make certain the H5T & H5P interfaces have been initialized */
- H5T_init();
- H5P_init();
-
- /* Initialize the atom group for the file IDs */
- if((ret_value=H5Ainit_group(H5_DATASET,H5A_DATASETID_HASHSIZE,H5D_RESERVED_ATOMS,NULL))!=FAIL)
- ret_value=H5_add_exit(&H5D_term_interface);
-
- FUNC_LEAVE(ret_value);
-} /* H5D_init_interface */
+ herr_t ret_value = SUCCEED;
+ FUNC_ENTER (H5D_init_interface, FAIL);
+
+ /* Initialize the atom group for the dataset IDs */
+ if ((ret_value=H5Ainit_group (H5_DATASET, H5A_DATASETID_HASHSIZE,
+ H5D_RESERVED_ATOMS,
+ (herr_t (*)(void*))H5D_close))!=FAIL) {
+ ret_value = H5_add_exit (H5D_term_interface);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
/*--------------------------------------------------------------------------
NAME
@@ -108,613 +107,802 @@ static herr_t H5D_init_interface(void)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-void H5D_term_interface (void)
+static void
+H5D_term_interface (void)
{
- H5Adestroy_group(H5_DATASET);
-} /* end H5D_term_interface() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5D_create
- PURPOSE
- Create a new HDF5 dataset object
- USAGE
- hid_t H5D_create(owner_id, type, name)
- hid_t owner_id; IN: Group/file which owns this object
- hobjtype_t type; IN: Type of object to create
- const char *name; IN: Name of the object
- RETURNS
- Returns ID (atom) on success, FAIL on failure
- DESCRIPTION
- This function actually creates a dataset object in a file (of course,
- output might not happen for some time).
---------------------------------------------------------------------------*/
-hid_t H5D_create(hid_t owner_id, hobjtype_t type, const char *name)
+ H5Adestroy_group (H5_DATASET);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dcreate
+ *
+ * Purpose: Creates a new dataset named NAME in file FILE_ID, opens the
+ * dataset for access, and associates with that dataset constant
+ * and initial persistent properties including the type of each
+ * datapoint as stored in the file (TYPE_ID), the size of the
+ * dataset (SPACE_ID), and other initial miscellaneous
+ * properties (CREATE_PARMS_ID).
+ *
+ * All arguments are copied into the dataset, so the caller is
+ * allowed to derive new types, data spaces, and creation
+ * parameters from the old ones and reuse them in calls to
+ * create other datasets.
+ *
+ * Return: Success: The object ID of the new dataset. At this
+ * point, the dataset is ready to receive its
+ * raw data. Attempting to read raw data from
+ * the dataset will probably return the fill
+ * value. The dataset should be closed when
+ * the caller is no longer interested in it.
+ *
+ * Failure: FAIL
+ *
+ * Errors:
+ * ARGS BADTYPE Not a data space.
+ * ARGS BADTYPE Not a dataset creation template.
+ * ARGS BADTYPE Not a file.
+ * ARGS BADTYPE Not a type.
+ * ARGS BADVALUE No name.
+ * DATASET CANTINIT Can't create dataset.
+ * DATASET CANTREGISTER Can't register dataset.
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, December 3, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dcreate (hid_t file_id, const char *name, hid_t type_id, hid_t space_id,
+ hid_t create_parms_id)
{
- H5D_t *new_dset; /* new dataset object to create */
- hid_t ret_value = SUCCEED;
- H5F_t *file = NULL;
-
- FUNC_ENTER(H5D_create, H5D_init_interface, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- H5ECLEAR;
-
- /* Convert atom arguments to pointers */
- if(H5Aatom_group(owner_id)!=H5_FILE)
- HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, FAIL);
- file = H5Aatom_object (owner_id);
-
- /* Allocate space for the new dataset */
- if((new_dset=HDcalloc(1, sizeof(H5D_t)))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
-
- /* Initialize the dataset object */
- new_dset->file = file;
- new_dset->tid=(-1); /* No type yet */
- new_dset->sid=(-1); /* No dimensions yet */
- H5F_addr_undef (&(new_dset->data_addr)); /* No data yet */
- new_dset->dirty = FALSE; /* There are no messages yet */
-
- /* Open (and create) a new file object */
- if (NULL==(new_dset->ent = H5G_create (file, name, H5D_MINHDR_SIZE))) {
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
- }
-
- /* Register the new datatype and get an ID for it */
- if((ret_value=H5Aregister_atom(H5_DATASET, (const VOIDP)new_dset))<0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL);
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
-
- FUNC_LEAVE(ret_value);
-} /* end H5D_create() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5D_find_name
- PURPOSE
- Get the OID for accessing an existing HDF5 dataset object
- USAGE
- hoid_t H5D_find_name(grp_id, type, name)
- hid_t grp_id; IN: Atom for group to search for dataset
- hobjtype_t type; IN: Type of object to search for (dataset in
- this case)
- const char *name; IN: Name of the object to search for
- RETURNS
- Returns ID (atom) on success, FAIL on failure
- DESCRIPTION
- This function finds for a dataset by name in a group.
---------------------------------------------------------------------------*/
-hid_t H5D_find_name(hid_t grp_id, hobjtype_t obj_type, const char *name)
+ H5F_t *f = NULL;
+ H5T_t *type = NULL;
+ H5P_t *space = NULL;
+ H5D_t *new_dset = NULL;
+ hid_t ret_value = FAIL;
+ const H5D_create_t *create_parms = NULL;
+
+ FUNC_ENTER (H5Dcreate, FAIL);
+ H5ECLEAR;
+
+ /* check arguments */
+ if (H5_FILE!=H5Aatom_group (file_id) ||
+ NULL==(f=H5Aatom_object (file_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a file*/
+ }
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL); /*no name*/
+ }
+ if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+ NULL==(type=H5Aatom_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a type*/
+ }
+ if (H5_DATASPACE!=H5Aatom_group (space_id) ||
+ NULL==(space=H5Aatom_object (space_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a data space */
+ }
+ if (create_parms_id>=0) {
+ if (H5C_DATASET_CREATE!=H5C_class (create_parms_id) ||
+ NULL==(create_parms=H5Aatom_object (create_parms_id))) {
+ /* Not a dataset creation template */
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL);
+ }
+ } else {
+ create_parms = &H5D_create_dflt;
+ }
+
+ /* build and open the new dataset */
+ if (NULL==(new_dset=H5D_create (f, name, type, space, create_parms))) {
+ HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL); /*can't create dataset*/
+ }
+
+ /* Register the new datatype and get an ID for it */
+ if ((ret_value=H5Aregister_atom (H5_DATASET, new_dset))<0) {
+ H5D_close (new_dset);
+ /* Can't register dataset */
+ HRETURN_ERROR (H5E_DATASET, H5E_CANTREGISTER, FAIL);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dopen
+ *
+ * Purpose: Finds a dataset named NAME in file FILE_ID, opens it, and
+ * returns its ID. The dataset should be close when the caller
+ * is no longer interested in it.
+ *
+ * Return: Success: A new dataset ID
+ *
+ * Failure: FAIL
+ *
+ * Errors:
+ * ARGS BADTYPE Not a file.
+ * ARGS BADVALUE No name.
+ * DATASET CANTREGISTER Can't register dataset.
+ * DATASET NOTFOUND Dataset not found.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Dopen (hid_t file_id, const char *name)
{
- H5F_t *file; /* Pointer to the file-store of this object */
- H5D_t *dset = NULL; /* The dataset */
- h5_datatype_t *type; /* The dataset's type */
- H5P_dim_t *dim; /* The dataset's dataspace */
- hid_t ret_value = SUCCEED;
- H5O_std_store_t store;
-
- FUNC_ENTER(H5D_find_name, H5D_init_interface, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- H5ECLEAR;
-
- /* Convert atom arguments to pointers */
- if(H5Aatom_group(grp_id)!=H5_FILE)
- HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, FAIL);
- file=H5Aatom_object(grp_id);
-
- /* Allocate space for the dataset */
- if(NULL==(dset=HDcalloc(1, sizeof(H5D_t))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
-
- /* Initialize file, group, name fields */
- dset->file = file;
- dset->dirty = FALSE;
-
- /* Open the dataset object */
- if (NULL==(dset->ent=H5G_open (file, name))) {
- HGOTO_ERROR (H5E_DATASET, H5E_NOTFOUND, FAIL);
- }
-
- /* Get the dataset's type (currently only atomic types) */
- if((type=HDcalloc(1,sizeof(h5_datatype_t)))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
- if (NULL==H5O_read (dset->file, NO_ADDR, dset->ent, H5O_SIM_DTYPE, 0,
- type))
- HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL);
- if((dset->tid=H5Aregister_atom(H5_DATATYPE, (const VOIDP)type))==FAIL)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL);
-
- /* Get the dataset's dimensionality (currently only simple dataspaces) */
- if((dim=HDcalloc(1,sizeof(H5P_dim_t)))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
- dim->type=H5P_TYPE_SIMPLE; /* for now... */
- if (NULL==(dim->s=H5O_read (dset->file, NO_ADDR, dset->ent,
- H5O_SIM_DIM, 0, NULL)))
- HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL);
- if((dset->sid=H5Aregister_atom(H5_DATASPACE, (const VOIDP)dim))==FAIL)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL);
-
- /* Get the dataset's data offset (currently only standard storage) */
- if (NULL==H5O_read (dset->file, NO_ADDR, dset->ent, H5O_STD_STORE, 0,
- &store))
- HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL);
- dset->data_addr=store.off;
-
- /* Register the new OID and get an ID for it */
- if((ret_value=H5Aregister_atom(H5_DATASET, (const VOIDP)dset))==FAIL)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL);
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
- if (dset) {
-#ifdef LATER
- /* We might need to free the `type' and `dim' fields also... */
-#endif
- H5MM_xfree (dset);
- }
- } /* end if */
-
- /* Normal function cleanup */
-
- FUNC_LEAVE(ret_value);
-} /* end H5D_find_name() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5Dset_info
- PURPOSE
- Set the type and dimensionality of a dataset.
- USAGE
- herr_t H5Dset_info(oid)
- hid_t oid; IN: Dataset object to modify
- hid_t tid; IN: Datatype object to use as node element
- hid_t sid; IN: Dimensionality object to use as dataspace
- RETURNS
- SUCCEED/FAIL
- DESCRIPTION
- This function sets the datatype and dataspace of a dataset.
---------------------------------------------------------------------------*/
-herr_t H5Dset_info(hid_t oid, hid_t tid, hid_t sid)
+ H5F_t *file = NULL; /*file holding the dataset */
+ H5D_t *dataset = NULL; /*the dataset */
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER (H5Dopen, FAIL);
+ H5ECLEAR;
+
+ /* Check args */
+ if (H5_FILE!=H5Aatom_group (file_id) ||
+ NULL==(file=H5Aatom_object (file_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a file*/
+ }
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL); /*no name*/
+ }
+
+ /* Find the dataset */
+ if (NULL==(dataset=H5D_open (file, name))) {
+ HRETURN_ERROR (H5E_DATASET, H5E_NOTFOUND, FAIL); /*dataset not found*/
+ }
+
+ /* Create an atom for the dataset */
+ if ((ret_value=H5Aregister_atom (H5_DATASET, dataset))<0) {
+ H5D_close (dataset);
+ /* Can't register dataset */
+ HRETURN_ERROR (H5E_DATASET, H5E_CANTREGISTER, FAIL);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dclose
+ *
+ * Purpose: Closes access to a dataset (DATASET_ID) and releases
+ * resources used by it. It is illegal to subsequently use that
+ * same dataset ID in calls to other dataset functions.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Errors:
+ * ARGS BADTYPE Not a dataset.
+ * DATASET CANTINIT Can't free.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dclose (hid_t dataset_id)
{
- H5D_t *dataset = NULL; /* dataset object to modify */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER(H5Dset_info, H5D_init_interface, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- H5ECLEAR;
-
- /* Check that we've received correctly typed parameters */
- if(H5Aatom_group(tid)!=H5_DATATYPE || H5Aatom_group(sid)!=H5_DATASPACE)
- HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, FAIL);
-
- /* Get the object */
- if((dataset=H5Aatom_object(oid))==NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
- /* Check that the datatype & dataspace haven't already been initialized */
- if(dataset->tid!=(-1) || dataset->sid!=(-1))
- HGOTO_ERROR(H5E_FUNC, H5E_ALREADYINIT, FAIL);
-
- /* Increment the reference count for the datatype */
- if(H5Ainc_ref(tid)==FAIL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
- dataset->tid=tid;
-
- /* Increment the reference count for the datatype */
- if(H5Ainc_ref(sid)==FAIL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
- dataset->sid=sid;
-
- /* Mark the dataset as modified (Huh? - QAK) */
- dataset->dirty = TRUE;
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
-
- FUNC_LEAVE(ret_value);
-} /* end H5Dset_info() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5Dget_info
- PURPOSE
- Get the type and dimensionality of a dataset.
- USAGE
- herr_t H5Dget_info(oid, tid, sid)
- hid_t oid; IN: Dataset object to query
- hid_t *tid; OUT: Datatype object to use as node element
- hid_t *sid; OUT: Dimensionality object to use as dataspace
- RETURNS
- SUCCEED/FAIL
- DESCRIPTION
- This function starts access to the datatype and dataspace of an
- existing dataset. H5Mendaccess must be called to release the datatype and
- dataspace returned from this function.
---------------------------------------------------------------------------*/
-herr_t H5Dget_info(hid_t oid, hid_t *tid, hid_t *sid)
+ H5D_t *dataset = NULL; /* dataset object to release */
+
+ FUNC_ENTER (H5Dclose, FAIL);
+ H5ECLEAR;
+
+ /* Check args */
+ if (H5_DATASET!=H5Aatom_group (dataset_id) ||
+ NULL==(dataset=H5Aatom_object (dataset_id)) ||
+ NULL==dataset->file) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a dataset*/
+ }
+
+ /*
+ * Decrement the counter on the dataset. It will be freed if the count
+ * reaches zero.
+ */
+ if (H5A_dec_ref (dataset_id)<0) {
+ HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL); /*can't free*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dread
+ *
+ * Purpose: Reads (part of) a DATASET from the file into application
+ * memory BUF. The part of the dataset to read is defined with
+ * SPACE_ID (if SPACE_ID is negative then we assume that the
+ * caller desires to read the entire dataset). The data points
+ * are converted from their file type to the TYPE_ID specified.
+ * Additional miscellaneous data transfer properties can be
+ * passed to this function with the XFER_PARMS_ID argument.
+ *
+ * The SPACE_ID can be the constant H5P_ALL in which case the
+ * destination (memory) data space is the same as the source
+ * (file) data space defined when the dataset was created.
+ *
+ * The XFER_PARMS_ID can be the constant H5C_DEFAULT in which
+ * case the default data transfer properties are used.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Errors:
+ * ARGS BADTYPE Not a data space.
+ * ARGS BADTYPE Not a data type.
+ * ARGS BADTYPE Not a dataset.
+ * ARGS BADTYPE Not xfer parms.
+ * ARGS BADVALUE No output buffer.
+ * DATASET READERROR Can't read data.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dread (hid_t dataset_id, hid_t type_id, hid_t space_id,
+ hid_t xfer_parms_id, void *buf/*out*/)
{
- H5D_t *dataset; /* dataset object to query */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER(H5Dget_info, H5D_init_interface, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- H5ECLEAR;
+ H5D_t *dataset = NULL;
+ const H5T_t *type = NULL;
+ const H5P_t *space = NULL;
+ const H5D_xfer_t *xfer_parms = NULL;
+
+ FUNC_ENTER (H5Dread, FAIL);
+ H5ECLEAR;
+
+ /* check arguments */
+ if (H5_DATASET!=H5Aatom_group (dataset_id) ||
+ NULL==(dataset=H5Aatom_object (dataset_id)) ||
+ NULL==dataset->file) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a dataset*/
+ }
+ if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+ NULL==(type=H5Aatom_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a data type*/
+ }
+ if (H5P_ALL!=space_id) {
+ if (H5_DATASPACE!=H5Aatom_group (space_id) ||
+ NULL==(space=H5Aatom_object (space_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a data space*/
+ }
+ }
+ if (H5C_DEFAULT==xfer_parms_id) {
+ xfer_parms = &H5D_xfer_dflt;
+ } else if (H5C_DATASET_XFER!=H5C_class (xfer_parms_id) ||
+ NULL==(xfer_parms=H5Aatom_object (xfer_parms_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not xfer parms*/
+ }
+ if (!buf) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL); /*no output buffer*/
+ }
+
+ /* read raw data */
+ if (H5D_read (dataset, type, space, xfer_parms, buf/*out*/)<0) {
+ HRETURN_ERROR (H5E_DATASET, H5E_READERROR, FAIL); /*can't read data*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dwrite
+ *
+ * Purpose: Writes (part of) a DATASET from application memory BUF to the
+ * file. The part of the dataset to write is defined with the
+ * SPACE_ID (if SPACE_ID is negative then we assume that the
+ * caller desires to write the entire dataset). The data points
+ * are converted from their current type (TYPE_ID) to their file
+ * data type. Additional miscellaneous data transfer properties
+ * can be passed to this function with the XFER_PARMS_ID
+ * argument.
+ *
+ * The SPACE_ID can be the constant H5P_ALL in which case the
+ * source (memory) data space is the same as the destination
+ * (file) memory space which was defined when the dataset was
+ * created.
+ *
+ * The XFER_PARMS_ID can be the constant H5C_DEFAULT in which
+ * case the default data transfer properties are used.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Errors:
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dwrite (hid_t dataset_id, hid_t type_id, hid_t space_id,
+ hid_t xfer_parms_id, const void *buf)
+{
+ H5D_t *dataset = NULL;
+ const H5T_t *type = NULL;
+ const H5P_t *space = NULL;
+ const H5D_xfer_t *xfer_parms = NULL;
+
+ FUNC_ENTER (H5Dwrite, FAIL);
+ H5ECLEAR;
+
+ /* check arguments */
+ if (H5_DATASET!=H5Aatom_group (dataset_id) ||
+ NULL==(dataset=H5Aatom_object (dataset_id)) ||
+ NULL==dataset->file) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a dataset*/
+ }
+ if (H5_DATATYPE!=H5Aatom_group (type_id) ||
+ NULL==(type=H5Aatom_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a data type*/
+ }
+ if (H5P_ALL!=space_id) {
+ if (H5_DATASPACE!=H5Aatom_group (space_id) ||
+ NULL==(space=H5Aatom_object (space_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not a data space*/
+ }
+ }
+ if (H5C_DEFAULT==xfer_parms_id) {
+ xfer_parms = &H5D_xfer_dflt;
+ } else if (H5C_DATASET_XFER!=H5C_class (xfer_parms_id) ||
+ NULL==(xfer_parms=H5Aatom_object (xfer_parms_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL); /*not xfer parms*/
+ }
+ if (!buf) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL); /*no output buffer*/
+ }
+
+ /* write raw data */
+ if (H5D_write (dataset, type, space, xfer_parms, buf)<0) {
+ HRETURN_ERROR (H5E_DATASET, H5E_READERROR, FAIL); /*can't write data*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
- /* Check that we've received correctly typed parameters */
- if(H5Aatom_group(oid)!=H5_DATASET)
- HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, FAIL);
- /* Get the object */
- if((dataset=H5Aatom_object(oid))==NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
- /* Check that the datatype & dataspace have already been initialized */
- if(dataset->tid==(-1) || dataset->sid==(-1))
- HGOTO_ERROR(H5E_DATASET, H5E_UNINITIALIZED, FAIL);
- /* Get the Dataset's IDs */
- if(H5Ainc_ref(dataset->tid)==FAIL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
- *tid=dataset->tid;
- if(H5Ainc_ref(dataset->sid)==FAIL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
- *sid=dataset->sid;
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
- } /* end if */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_find_name
+ *
+ * Purpose: This is a callback for H5Mfind_name(). It does the same
+ * thing as H5Dopen() except it takes an extra argument which
+ * isn't used.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Errors:
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5D_find_name (hid_t file_id, group_t UNUSED, const char *name)
+{
+ return H5Dopen (file_id, name);
+}
+
+
+
+
+
+
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_create
+ *
+ * Purpose: Creates a new dataset with name NAME in file F and associates
+ * with it a datatype TYPE for each element as stored in the
+ * file, dimensionality information or dataspace SPACE, and
+ * other miscellaneous properties CREATE_PARMS. All arguments
+ * are deep-copied before being associated with the new dataset,
+ * so the caller is free to subsequently modify them without
+ * affecting the dataset.
+ *
+ * Return: Success: Pointer to a new dataset
+ *
+ * Failure: NULL
+ *
+ * Errors:
+ * DATASET CANTINIT Can't update dataset header.
+ * DATASET CANTINIT Problem with the dataset name.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5D_t *
+H5D_create (H5F_t *f, const char *name, const H5T_t *type, const H5P_t *space,
+ const H5D_create_t *create_parms)
+{
+ H5D_t *new_dset = NULL;
+ H5D_t *ret_value = NULL;
+ H5O_cstore_t cstore; /*contiguous storage message */
+
+ FUNC_ENTER (H5D_create, NULL);
+
+ /* check args */
+ assert (f);
+ assert (name && *name);
+ assert (type);
+ assert (space);
+ assert (create_parms);
+
+ /* Initialize the dataset object */
+ new_dset = H5MM_xcalloc (1, sizeof(H5D_t));
+ new_dset->file = f;
+ new_dset->type = H5T_copy (type);
+ new_dset->space = H5P_copy (space);
+ new_dset->create_parms = *create_parms;
+ H5F_addr_undef (&(new_dset->data_addr)); /* No data yet */
+
+ /*
+ * Open (and create) a new file object and update the object header
+ * immediately with the new information so when others access the dataset
+ * they see the most current info. This `write through the dataset'
+ * policy is used throughout this package, and because the object header
+ * is cached it shouldn't cause any disk activity.
+ */
+ if (NULL==(new_dset->ent = H5G_create (f, name, H5D_MINHDR_SIZE))) {
+ /* Problem with the dataset name */
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL);
+ }
+
+ /* Update the type and space header messages */
+ if (H5O_modify (f, NO_ADDR, new_dset->ent, H5O_DTYPE, 0,
+ new_dset->type)<0 ||
+ H5P_modify (f, new_dset->ent, new_dset->space)<0) {
+ /* Can't update type or space header messages */
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL);
+ }
+
+ /* Update layout message */
+ switch (new_dset->create_parms.layout) {
+ case H5D_CONTIGUOUS:
+ cstore.size = H5T_get_size (type) * H5P_get_npoints (space);
+ if (H5MF_alloc (f, H5MF_RAW, cstore.size, &(cstore.addr))<0) {
+ /* Can't allocate raw file storage */
+ HGOTO_ERROR (H5E_DATASET, H5E_NOSPACE, NULL);
+ }
+ if (H5O_modify (f, NO_ADDR, new_dset->ent, H5O_CSTORE, 0, &cstore)<0) {
+ /* Can't update dataset object header */
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL);
+ }
+ new_dset->data_addr = cstore.addr;
+ break;
+
+ default:
+ assert ("not implemented yet" && 0);
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, NULL);
+ }
+
+ /* Success */
+ ret_value = new_dset;
+
+
+ done:
+ if (!ret_value && new_dset) {
+ if (new_dset->type) H5T_close (new_dset->type);
+ if (new_dset->space) H5P_close (new_dset->space);
+ if (new_dset->ent) H5G_close (f, new_dset->ent);
+ new_dset->file = NULL;
+ H5MM_xfree (new_dset);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_open
+ *
+ * Purpose: Finds a dataset named NAME in file F and builds a descriptor
+ * for it, opening it for access.
+ *
+ * Return: Success: Pointer to a new dataset descriptor.
+ *
+ * Failure: NULL
+ *
+ * Errors:
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5D_t *
+H5D_open (H5F_t *f, const char *name)
+{
+ H5D_t *dataset = NULL; /*the dataset which was found */
+ H5D_t *ret_value = NULL; /*return value */
+ H5O_cstore_t cstore; /*contiguous storage message */
- /* Normal function cleanup */
+ FUNC_ENTER (H5D_open, NULL);
- FUNC_LEAVE(ret_value);
-} /* end H5Dset_info() */
+ /* check args */
+ assert (f);
+ assert (name && *name);
-/*--------------------------------------------------------------------------
- NAME
- H5Dread
- PURPOSE
- Read data from a dataset
- USAGE
- herr_t H5Dread(oid)
- hid_t oid; IN: Dataset to read
- hid_t did; IN: Dimensionality object to use as dataspace for I/O
- VOIDP buf; IN: Buffer to fill with data from the file
- RETURNS
- SUCCEED/FAIL
- DESCRIPTION
- This function reads dataset object data from the file. The dataspace
- ID determines the slice/hyper-slab/portion of the dataset to write.
- H5P_ALL is a special value which indicates that the entire dataset is
- to be written out. (For datasets which have a scalar dataspace for the
- entire dataset, this is somewhat redundant.... :-)
---------------------------------------------------------------------------*/
-herr_t H5Dread(hid_t oid, hid_t did, VOIDP buf)
-{
- H5D_t *dataset; /* dataset object to do I/O on */
- void *readbuf=NULL; /* pointer to buffer to write out */
- uintn free_buf=0; /* if temporary conversion buffer needs to be free'd */
- uintn toread; /* number of bytes to read in */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER(H5Dread, H5D_init_interface, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- H5ECLEAR;
-
- /* Check that we've received correctly typed parameters */
- if(H5Aatom_group(did)!=H5_DATASPACE || H5Aatom_group(oid)!=H5_DATASET)
- HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, FAIL);
- if(buf==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL);
-
- /* Get the object */
- if((dataset=H5Aatom_object(oid))==NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
-
- /* Check that the datatype & dataspace have already been initialized */
- if(dataset->tid==(-1) || dataset->sid==(-1) ||
- !H5F_addr_defined (&(dataset->data_addr)))
- HGOTO_ERROR(H5E_FUNC, H5E_UNINITIALIZED, FAIL);
-
- /* Compute the number of bytes to read */
- if(did==H5P_ALL) /* Check if we are reading the entire dataset */
- toread=H5Tsize(dataset->tid,BTRUE)*H5Pnelem(dataset->sid);
- else
- HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL);
-
- /* Check memory to disk datatype conversions, etc. */
-/* This is totally hacked up code, but I'm in a hurry. ;-/ -QAK */
- if(H5Tarch(dataset->tid)!=H5T_ARCH_TYPE)
- {
- if((readbuf=HDmalloc(toread))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
- free_buf=1;
- } /* end if */
- else
- readbuf=buf;
-
+ dataset = H5MM_xcalloc (1, sizeof(H5D_t));
+ dataset->file = f;
- /* Read data from disk */
- if (H5F_block_read (dataset->file, &(dataset->data_addr), toread,
- readbuf)<0) {
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL);
- }
+ /* Open the dataset object */
+ if (NULL==(dataset->ent=H5G_open (f, name))) {
+ HGOTO_ERROR (H5E_DATASET, H5E_NOTFOUND, NULL); /*not found*/
+ }
+
+ /* Get the type and space */
+ if (NULL==(dataset->type = H5O_read (f, NO_ADDR, dataset->ent, H5O_DTYPE,
+ 0, NULL)) ||
+ NULL==(dataset->space = H5P_read (f, dataset->ent))) {
+ /* Can't load type of space info from dataset header */
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL);
+ }
+
+#if 0
+ if((type=HDcalloc(1,sizeof(H5T_t)))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
+ if (NULL==H5O_read (dset->file, NO_ADDR, dset->ent, H5O_SIM_DTYPE, 0,
+ type))
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL);
+ if((dset->tid=H5Aregister_atom(H5_DATATYPE, (const VOIDP)type))==FAIL)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL);
- if(free_buf!=0)
- H5D_convert_buf(buf,readbuf,toread,H5Tsize(dataset->tid,BTRUE));
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
- if(free_buf!=0) /* check if we need to release the conversion buffer */
- HDfree(readbuf);
+ /* Get the dataset's dimensionality (currently only simple dataspaces) */
+ if((dim=HDcalloc(1,sizeof(H5P_t)))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
+ dim->type=H5P_TYPE_SIMPLE; /* for now... */
+ if (NULL==(dim->s=H5O_read (dset->file, NO_ADDR, dset->ent,
+ H5O_SDSPACE, 0, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL);
+ if((dset->sid=H5Aregister_atom(H5_DATASPACE, (const VOIDP)dim))==FAIL)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL);
+#endif
- FUNC_LEAVE(ret_value);
-} /* end H5Dread() */
+ /* Get the raw data storage info */
+ if (H5O_read (dataset->file, NO_ADDR, dataset->ent, H5O_CSTORE, 0,
+ &cstore)) {
+ dataset->create_parms.layout = H5D_CONTIGUOUS;
+ dataset->data_addr = cstore.addr;
+ } else {
+ assert ("not implemented yet" && 0);
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, NULL);
+ }
+
+ /* Success */
+ ret_value = dataset;
+
-/*--------------------------------------------------------------------------
- NAME
- H5Dwrite
- PURPOSE
- Write data for a dataset
- USAGE
- herr_t H5Dwrite(oid)
- hid_t oid; IN: Dataset object to modify
- hid_t did; IN: Dimensionality object to use as dataspace for I/O
- VOIDP buf; IN: Buffer with data to write to the file
- RETURNS
- SUCCEED/FAIL
- DESCRIPTION
- This function writes dataset object data to the file. The dataspace
- ID determines the slice/hyper-slab/portion of the dataset to write.
- H5P_ALL is a special value which indicates that the entire dataset is
- to be written out. (For datasets which have a scalar dataspace for the
- entire dataset, this is somewhat redundant.... :-)
---------------------------------------------------------------------------*/
-herr_t H5Dwrite(hid_t oid, hid_t did, VOIDP buf)
+ done:
+ if (!ret_value && dataset) {
+ if (dataset->ent) H5G_close (f, dataset->ent);
+ if (dataset->type) H5T_close (dataset->type);
+ if (dataset->space) H5P_close (dataset->space);
+ dataset->file = NULL;
+ H5MM_xfree (dataset);
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_close
+ *
+ * Purpose: Insures that all data has been saved to the file, closes the
+ * dataset object header, and frees all resources used by the
+ * descriptor.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Errors:
+ * DATASET CANTINIT Couldn't free the type or space,
+ * but the dataset was freed anyway.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_close (H5D_t *dataset)
{
- H5D_t *dataset; /* dataset object to do I/O on */
- uintn towrite; /* number of bytes to write out */
- void *writebuf=NULL; /* pointer to buffer to write out */
- uintn free_buf=0; /* if temporary conversion buffer needs to be free'd */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER(H5Dwrite, H5D_init_interface, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- H5ECLEAR;
-
- /* Check that we've received correctly typed parameters */
- if(H5Aatom_group(did)!=H5_DATASPACE || H5Aatom_group(oid)!=H5_DATASET)
- HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, FAIL);
- if(buf==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL);
-
- /* Get the object */
- if((dataset=H5Aatom_object(oid))==NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
-
- /* Check that the datatype & dataspace have already been initialized */
- if(dataset->tid==(-1) || dataset->sid==(-1))
- HGOTO_ERROR(H5E_FUNC, H5E_UNINITIALIZED, FAIL);
-
- /* Compute the number of bytes to write out */
- if(did==H5P_ALL) /* Check if we are writing out the entire dataset */
- towrite=H5Tsize(dataset->tid,BTRUE)*H5Pnelem(dataset->sid);
- else
- HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL);
-
- /* Check if we have space for the dataset yet */
- if (!H5F_addr_defined (&(dataset->data_addr))) {
- if (H5MF_alloc (dataset->file, H5MF_RAW, towrite,
- &(dataset->data_addr)/*out*/)<0) {
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
- }
- dataset->dirty = TRUE;
- }
-
- /* Check memory to disk datatype conversions, etc. */
-/* This is totally hacked up code, but I'm in a hurry. ;-/ -QAK */
- if(H5Tarch(dataset->tid)!=H5T_ARCH_TYPE)
- {
- if((writebuf=HDmalloc(towrite))==NULL)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
- H5D_convert_buf(writebuf,buf,towrite,H5Tsize(dataset->tid,BTRUE));
- free_buf=1;
- } /* end if */
- else
- writebuf=buf;
-
- /* Write the data out to disk */
- if (H5F_block_write (dataset->file, &(dataset->data_addr), towrite,
- writebuf)<0) {
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL);
- }
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
- if(free_buf!=0) /* check if we need to release the conversion buffer */
- HDfree(writebuf);
-
- FUNC_LEAVE(ret_value);
-} /* end H5Dwrite() */
+ hbool_t free_failed;
+
+ FUNC_ENTER (H5D_close, FAIL);
-/*--------------------------------------------------------------------------
- NAME
- H5D_flush
- PURPOSE
- Flush an an HDF5 dataset object to disk.
- USAGE
- herr_t H5D_flush(oid)
- hid_t oid; IN: Object to flush to disk
- RETURNS
- SUCCEED/FAIL
- DESCRIPTION
- This function flushes a dataset to disk. (i.e. makes the disk version
- agree with what's in memory, it does _not_ update the memory version with
- any changes on disk) This function is primarily called from H5Mflush, but
- internal library routines may call it also.
---------------------------------------------------------------------------*/
-herr_t H5D_flush(hid_t oid)
+ /* check args */
+ assert (dataset && dataset->file);
+
+ /* Close the dataset object */
+ H5G_close (dataset->file, dataset->ent);
+ dataset->ent = NULL;
+
+ /*
+ * Release dataset type and space - there isn't much we can do if one of
+ * these fails, so we just continue.
+ */
+ free_failed = (H5T_close (dataset->type)<0 ||
+ H5P_close (dataset->space)<0);
+
+ /*
+ * Free memory. Before freeing the memory set the file pointer to NULL.
+ * We always check for a null file pointer in other H5D functions to be
+ * sure we're not accessing an already freed dataset (see the assert()
+ * above).
+ */
+ dataset->file = NULL;
+ H5MM_xfree (dataset);
+
+ if (free_failed) {
+ /* Couldn't free the type or space, but the dataset was freed anyway. */
+ HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL);
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_read
+ *
+ * Purpose: Reads (part of) a DATASET into application memory BUF. The
+ * SPACE argument determines what part of the dataset to read
+ * (the whole thing is read if SPACE is null) and individual
+ * data points are translated from their file data type to the
+ * specified TYPE. The XFER_PARMS contains additional
+ * miscellaneous properties that control the data transfer.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_read (H5D_t *dataset, const H5T_t *type, const H5P_t *space,
+ const H5D_xfer_t *xfer_parms, void *buf/*out*/)
{
- H5D_t *dataset; /* dataset object to release */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER(H5D_flush, H5D_init_interface, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- H5ECLEAR;
-
- /* Get the object */
- if((dataset=H5Aatom_object(oid))==NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
-
- if (dataset->dirty) {
-
- /*
- * Modify/create messages for this dataset. Begin with the
- * type information.
- */
- if (H5Tis_atomic (dataset->tid)) {
- h5_datatype_t *type=H5Aatom_object(dataset->tid);
-
- if (H5O_modify (dataset->file, NO_ADDR, dataset->ent,
- H5O_SIM_DTYPE, 0, type)<0) {
- /* Can't create/update type message */
- HGOTO_ERROR (H5E_INTERNAL, H5E_CANTCREATE, FAIL);
- }
- } else {
- /* Not an atomic datatype */
- HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL);
- }
-
- /*
- * Modify/create the dimensionality information.
- */
- if (H5Pis_simple (dataset->sid)) {
- H5P_dim_t *dim=H5Aatom_object(dataset->sid);
-
- if (H5O_modify (dataset->file, NO_ADDR, dataset->ent,
- H5O_SIM_DIM, 0, dim->s)<0) {
- /* Can't create/update dimensionality message */
- HGOTO_ERROR (H5E_INTERNAL, H5E_CANTCREATE, FAIL);
- }
- } else {
- /* Not an atomic datatype */
- HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL);
- }
-
- /*
- * Modify/create the dataset's storage information.
- */
- if (H5F_addr_defined (&(dataset->data_addr))) {
- H5O_std_store_t store; /* standard storage info */
-
- store.len = H5Tsize (dataset->tid, BTRUE) * H5Pnelem (dataset->sid);
- store.off = dataset->data_addr;
- if (H5O_modify (dataset->file, NO_ADDR, dataset->ent,
- H5O_STD_STORE, 0, &store)<0) {
- /* Can't create/modify storage information */
- HGOTO_ERROR (H5E_INTERNAL, H5E_CANTCREATE, FAIL);
- }
- }
-
- dataset->dirty = FALSE; /*it's clean now*/
- }
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
-
- FUNC_LEAVE(ret_value);
-} /* end H5D_flush() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5D_release
- PURPOSE
- Release access to an HDF5 dataset object.
- USAGE
- herr_t H5D_release(oid)
- hid_t oid; IN: Object to release access to
- RETURNS
- SUCCEED/FAIL
- DESCRIPTION
- This function releases a dataset from active use by a user.
---------------------------------------------------------------------------*/
-herr_t H5D_release(hid_t oid)
+ size_t nbytes;
+
+ FUNC_ENTER (H5D_read, FAIL);
+
+ /* check args */
+ assert (dataset && dataset->file);
+ assert (type);
+ assert (xfer_parms);
+ assert (buf);
+
+ if (H5D_CONTIGUOUS!=dataset->create_parms.layout) {
+ /* Layout is not supported yet */
+ HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL);
+ }
+ if (H5T_cmp (type, dataset->type)) {
+ /* Type conversion not supported yet */
+ HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL);
+ }
+ if (space && H5P_cmp (space, dataset->space)) {
+ /* Space conversion not supported yet */
+ HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL);
+ }
+
+ /* Compute the size of the request */
+ nbytes = H5T_get_size (dataset->type) * H5P_get_npoints (dataset->space);
+
+ /* Read the data from disk */
+ if (H5F_block_read (dataset->file, &(dataset->data_addr), nbytes, buf)<0) {
+ HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL); /*read failed*/
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_write
+ *
+ * Purpose: Writes (part of) a DATASET to a file from application memory
+ * BUF. The SPACE argument determines what part of the dataset
+ * to write (the whole thing is read if SPACE is null) and
+ * individual data points are translated from their memory data
+ * type (TYPE) to the file data type. The XFER_PARMS contains
+ * additional miscellaneous properties that control the data
+ * transfer.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_write (H5D_t *dataset, const H5T_t *type, const H5P_t *space,
+ const H5D_xfer_t *xfer_parms, const void *buf)
{
- H5D_t *dataset; /* dataset object to release */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER(H5D_release, H5D_init_interface, FAIL);
-
- /* Clear errors and check args and all the boring stuff. */
- H5ECLEAR;
-
- /* Get the dataset so we can check for changes and release it */
- if((dataset=H5Aatom_object(oid))==NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
-
- /* Check if we have information to flush to the file... */
- if(dataset->dirty && H5D_flush(oid)<0) {
- /* Can't flush dataset */
- HGOTO_ERROR (H5E_OHDR, H5E_CANTFLUSH, FAIL);
- }
-
- /* Close the dataset object */
- H5G_close (dataset->file, dataset->ent);
- dataset->ent = NULL;
+ size_t nbytes;
+
+ FUNC_ENTER (H5D_write, FAIL);
+
+ /* check args */
+ assert (dataset && dataset->file);
+ assert (type);
+ assert (xfer_parms);
+ assert (buf);
+
+ if (H5D_CONTIGUOUS!=dataset->create_parms.layout) {
+ /* Layout is not supported yet */
+ HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL);
+ }
+ if (H5T_cmp (type, dataset->type)) {
+ /* Type conversion not supported yet */
+ HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL);
+ }
+ if (space && H5P_cmp (space, dataset->space)) {
+ /* Space conversion not supported yet */
+ HRETURN_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL);
+ }
+
+ /* Compute the size of the request */
+ nbytes = H5T_get_size (dataset->type) * H5P_get_npoints (dataset->space);
- /* Release the atoms for the datatype and dataspace */
- H5Adec_ref(dataset->tid);
- H5Adec_ref(dataset->sid);
- /* release the memory used for the dataset */
- H5MM_xfree (dataset);
-
- /* Delete the dataset from the atom group */
- if(H5Aremove_atom(oid)==NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
-
-done:
- if(ret_value == FAIL)
- { /* Error condition cleanup */
-
- } /* end if */
-
- /* Normal function cleanup */
+ /* Write the data out to disk */
+ if (H5F_block_write (dataset->file, &(dataset->data_addr), nbytes, buf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL); /*write failed*/
+ }
- FUNC_LEAVE(ret_value);
-} /* end H5D_release() */
+ FUNC_LEAVE (SUCCEED);
+}