diff options
Diffstat (limited to 'src/H5D.c')
-rw-r--r-- | src/H5D.c | 1482 |
1 files changed, 835 insertions, 647 deletions
@@ -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); +} |