diff options
author | Robb Matzke <matzke@llnl.gov> | 1997-12-10 22:41:07 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1997-12-10 22:41:07 (GMT) |
commit | 082dd8cda9ef3d49be23dfce49e10dd30d0758bc (patch) | |
tree | e60a32468ba14f758849f34454fdd8722b72edaa /src/H5D.c | |
parent | 3aee91269b83b09a186d214c55873fbbfa15602d (diff) | |
download | hdf5-082dd8cda9ef3d49be23dfce49e10dd30d0758bc.zip hdf5-082dd8cda9ef3d49be23dfce49e10dd30d0758bc.tar.gz hdf5-082dd8cda9ef3d49be23dfce49e10dd30d0758bc.tar.bz2 |
[svn-r139] ./src/*.[ch]
Removed the interface initialization argument from
FUNC_ENTER() and made it a locally-defined preprocessor
symbol, INTERFACE_INIT.
Changed `offset' to `address' and `length' to `size' in
documentation so it's more consistent. `Offset' still appears
occassionally when it refers to a byte offset within some
other data structure.
Moved interface termination function prototypes from public
header files to .c files and made them static.
./src/H5.c
./src/H5public.h
Added H5init() because it's possible that the predefined data
types are not initialized. This happens only if the first
call to the hdf5 library passes a predefined data type symbol
as an argument. There should be some way to fix this...
./src/H5A.c
./src/H5Aprivate.h
./src/H5Apublic.h
The free_func returns SUCCEED or FAIL, although the return
value is ignored by H5A. This is so we can use the various
H5*_close() functions to free things.
H5Ainc_ref() and H5Adec_ref() are no longer public. Many of
the other atom functions should also be made private, but I'll
save that for later...
Added additional template groups called H5_TEMPLATE_0 through
H5_TEMPLATE_7 that are used by the various template
subclasses.
Increased the number of bits used for atom groups to prevent
negative atoms.
./src/H5AC.c
./src/H5ACprivate.h
Changed H5AC_new() to H5AC_create() to make names more consistent.
./src/H5B.c
./src/H5Bprivate.h
Changed H5B_new() to H5B_create() to make names more consistent.
./src/H5C.c
./src/H5Cprivate.h
./src/H5Cpublic.h
Now supports multiple subclasses of templates, although it's
done with big switch statements. The default values for
templates are defined in the source file to which that
template belongs. This got rid of lots of needless
preprocessor constants.
Added H5Ccreate() to create a new template. Changed
H5C_release() to H5Cclose() to make the naming more
consistent.
./src/H5D.c
./src/H5Dprivate.h
./src/H5Dpublic.h
Enhanced to use the new dataset interface, and uses the enhanced
data type and data space interfaces, which haven't been
completely implemented. The dataset interface doesn't handle
non-contiguous storage, compression, or data type and space
conversions yet.
./src/H5F.c
./src/H5Fprivate.h
./src/H5Fpublic.h
Removed H5Fflush() since just calls H5F_flush(), which doesn't
do what the user would probably think it does, namely, flush
everything. It only flushes those things sitting in the H5AC
cache and the boot block.
Changed the `file_create_parms' field of H5F_low_t to just
`create_parms' since the `file' part is obvious.
./src/H5Fistore.c
Added some support for external files. Mostly just in the
file format and not supported much by the library yet. I need
to finish some dataset functions first.
Changed H5F_istore_new() to H5F_istore_create() to make names
more uniform across packages.
./src/H5Flow.c
Flushing a file causes the file to be physically extended to
the logical eof. This prevents H5F_open() from thinking a
file has been truncated. Most of the time the file will
already be that large, and when it isn't Unix will often just
allocate the final block anyway.
./src/H5G.c
./src/H5Gent.c
./src/H5Gnode.c
./src/H5Gpkg.h
./src/H5Gprivate.h
./src/H5Gstab.c
Removed H5G_basename()
Removed (temporarily) data type information from symbol table
entries and renamed H5G_CACHED_SDATA to H5G_CACHED_SDSPACE to
reflect that it's a simple data space and has nothing to do
with raw data.
Changed H5G_node_new() to H5G_node_create() and H5G_stab_new()
to H5G_stab_create() to make names more uniform across
packages.
Fixed an undefined address bug that happens when H5G_node_debug()
program doesn't pass enough info to H5G_node_load().
./src/H5H.c
./src/H5Hprivate.h
Changed H5H_new() to H5H_create() to make the names more
uniform across packages.
./src/H5M.c
./src/H5Mprivate.h
./src/H5Mpublic.h
Nulled all the create functions. Most of the other callbacks
are to public functions. Removed H5Mcreate().
Changed hobjtype_t to group_t since it has to be the same
thing anyway.
./src/H5O.c
./src/H5Oprivate.h
./src/H5Osdim.c
./src/H5Osdtyp.c
Changed H5O_SIM_DIM to H5O_SDSPACE (simple data space) since
`simple data space' is its official name, not `simple
dimensions'. Will eventually add H5O_CDSPACE for comples data
spaces. Changed _sim_dim_ to _dspace_.
Replaced H5O_SIM_DTYPE and the compound data type messages
with a single H5O_DTYPE message. Changed _sim_dtype_ to _dtype_.
Changed H5O_STD_STORE to H5O_CSTORE (contiguous storage) since
contiguous storage is not necessarily standard. Changed
_std_store_ to _cstore_ in H5Ocstore.c
Added the H5O_EFL (external file list) message.
Changed H5O_new() to H5O_create() to make names more uniform
across packages.
./src/H5Oefl.c NEW
External file list message for specifying which non-hdf5 files
contain raw data for a dataset.
./src/H5P.c
./src/H5Pprivate.h
./src/H5Ppublic.h
Renamed and moved data structures to make the names conform to
our naming scheme.
./src/H5T.c
./src/H5Tprivate.h
./src/H5Tpublic.h
./src/H5Tpkg.h NEW
Data structures redesigned to be more flexible. The interface
was redesigned to make it more regular and to make some names
more uniform across packages.
./src/H5detect.c
Output was changed to produce a file that conforms to the hdf5
coding standard.
./src/Makefile.in
Generates H5Tinit.c by running H5detect.
./src/debug.c
Moved command argument processing.
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); +} |