summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-04-28 13:59:08 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-04-28 13:59:08 (GMT)
commit66071d5078ad9841c8fbb430881ae2c6e059886e (patch)
tree163bf340ff1c2dcc9aebc35a1bea296a8da0e623 /src
parent4dcf59ae4461eec74a180d77783d9064d2aa3a58 (diff)
downloadhdf5-66071d5078ad9841c8fbb430881ae2c6e059886e.zip
hdf5-66071d5078ad9841c8fbb430881ae2c6e059886e.tar.gz
hdf5-66071d5078ad9841c8fbb430881ae2c6e059886e.tar.bz2
[svn-r377] Changes since 19980424
---------------------- ./src/H5A.c ./src/H5T.c Fixed memory leaks. More to come later but PureAtria doesn't make a Linux version of purify and the free version doesn't compile with the new SMP Linux kernels so I had to debug over the internet on a day that Sprint seemed to be having routing problems... oh well. I got rid of most of the leaks. ./src/H5Apublic.h Includes H5Ipublic.h for types in the header file. ./src/H5O.c Comments improved for H5O_read() ./test/tattr.c Removed a non-ANSI empty initializer. ./test/dsets.c Include <string.h> ./test/istore.c Fixed a non-ANSI pointer conversion.
Diffstat (limited to 'src')
-rw-r--r--src/H5A.c155
-rw-r--r--src/H5Apublic.h2
-rw-r--r--src/H5F.c4
-rw-r--r--src/H5Ffamily.c27
-rw-r--r--src/H5Fsplit.c443
-rw-r--r--src/H5I.c1
-rw-r--r--src/H5O.c6
-rw-r--r--src/H5P.c36
-rw-r--r--src/H5T.c57
9 files changed, 586 insertions, 145 deletions
diff --git a/src/H5A.c b/src/H5A.c
index 9d2cc41..0c08dc8 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -105,6 +105,7 @@ H5A_init_interface(void)
static void
H5A_term_interface(void)
{
+ H5I_destroy_group (H5_ATTR);
}
@@ -213,14 +214,13 @@ H5Acreate(hid_t loc_id, const char *name, hid_t datatype, hid_t dataspace,
* April 2, 1998
*
* Modifications:
- *
*-------------------------------------------------------------------------
*/
static hid_t
H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, const H5S_t *space)
{
H5A_t *attr = NULL;
- H5A_t *found_attr = NULL;
+ H5A_t found_attr;
intn seq=0;
hid_t ret_value = FAIL;
@@ -256,14 +256,19 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, const H5
/* Read in the existing attributes to check for duplicates */
seq=0;
- while((found_attr=H5O_read(&(attr->ent), H5O_ATTR, seq, NULL))!=NULL)
- {
- /* Compare found attribute name to new attribute name reject creation if names are the same */
- if(HDstrcmp(found_attr->name,attr->name)==0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, FAIL,
- "attribute already exists");
- seq++;
- } /* end while */
+ while(H5O_read(&(attr->ent), H5O_ATTR, seq, &found_attr)!=NULL) {
+ /*
+ * Compare found attribute name to new attribute name reject creation
+ * if names are the same.
+ */
+ if(HDstrcmp(found_attr.name,attr->name)==0) {
+ H5O_reset (H5O_ATTR, &found_attr);
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCREATE, FAIL,
+ "attribute already exists");
+ }
+ H5O_reset (H5O_ATTR, &found_attr);
+ seq++;
+ } /* end while */
/* Create the attribute message and save the attribute index */
if (H5O_modify(&(attr->ent), H5O_ATTR, H5O_NEW_MESG, 0, attr) < 0)
@@ -309,8 +314,8 @@ done:
static int
H5A_get_index(H5G_entry_t *ent, const char *name)
{
- H5A_t *found_attr = NULL;
- int ret_value = FAIL;
+ H5A_t found_attr;
+ int ret_value=FAIL, i;
FUNC_ENTER(H5A_get_index, FAIL);
@@ -318,18 +323,25 @@ H5A_get_index(H5G_entry_t *ent, const char *name)
assert(name);
/* Look up the attribute for the object */
- ret_value=0;
- while((found_attr=H5O_read(ent, H5O_ATTR, ret_value, NULL))!=NULL)
- {
- /* Compare found attribute name to new attribute name reject creation if names are the same */
- if(HDstrcmp(found_attr->name,name)==0)
- break;
- ret_value++;
- } /* end while */
- if(found_attr==NULL) {
+ i=0;
+ while(H5O_read(ent, H5O_ATTR, i, &found_attr)!=NULL) {
+ /*
+ * Compare found attribute name to new attribute name reject creation
+ * if names are the same.
+ */
+ if(HDstrcmp(found_attr.name,name)==0) {
+ H5O_reset (H5O_ATTR, &found_attr);
+ ret_value = i;
+ break;
+ }
+ H5O_reset (H5O_ATTR, &found_attr);
+ i++;
+ } /* end while */
+
+ if(ret_value<0) {
HRETURN_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL,
"attribute not found");
- }
+ }
FUNC_LEAVE(ret_value);
} /* H5A_get_index() */
@@ -479,13 +491,8 @@ H5A_open(H5G_entry_t *ent, unsigned idx)
/* check args */
assert(ent);
- /* Build the attribute information */
- if((attr = H5MM_xcalloc(1, sizeof(H5A_t)))==NULL)
- HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "unable to allocate space for attribute info");
-
/* Read in attribute with H5O_read() */
- if (NULL==(H5O_read(ent, H5O_ATTR, idx, attr))) {
+ if (NULL==(attr=H5O_read(ent, H5O_ATTR, idx, attr))) {
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL,
"unable to load attribute info from dataset header");
}
@@ -1077,7 +1084,7 @@ H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op, void *op_data)
{
H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */
void *obj = NULL;
- H5A_t *found_attr = NULL;
+ H5A_t found_attr;
int ret_value = 0;
FUNC_ENTER(H5Anum_attrs, FAIL);
@@ -1105,12 +1112,15 @@ H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op, void *op_data)
/* Look up the attribute for the object */
if((int)*attr_num<H5O_count(ent, H5O_ATTR)) /* Make certain the start point is reasonable */
- while((found_attr=H5O_read(ent, H5O_ATTR, *attr_num, NULL))!=NULL)
+ while(H5O_read(ent, H5O_ATTR, *attr_num, &found_attr)!=NULL)
{
/* Compare found attribute name to new attribute name reject creation if names are the same */
(*attr_num)++;
- if((ret_value=op(loc_id,found_attr->name,op_data))!=0)
+ if((ret_value=op(loc_id,found_attr.name,op_data))!=0) {
+ H5O_reset (H5O_ATTR, &found_attr);
break;
+ }
+ H5O_reset (H5O_ATTR, &found_attr);
} /* end while */
FUNC_LEAVE(ret_value);
@@ -1140,11 +1150,11 @@ H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op, void *op_data)
herr_t
H5Adelete(hid_t loc_id, const char *name)
{
- H5A_t *found_attr = NULL;
+ H5A_t found_attr;
H5G_entry_t *ent = NULL; /* Symbol table entry of object to attribute */
void *obj = NULL;
- intn idx=0;
- hid_t ret_value = FAIL;
+ intn idx=0, found=-1;
+ herr_t ret_value = FAIL;
FUNC_ENTER(H5Aopen_name, FAIL);
@@ -1168,20 +1178,26 @@ H5Adelete(hid_t loc_id, const char *name)
/* Look up the attribute for the object */
idx=0;
- while((found_attr=H5O_read(ent, H5O_ATTR, idx, NULL))!=NULL)
- {
- /* Compare found attribute name to new attribute name reject creation if names are the same */
- if(HDstrcmp(found_attr->name,name)==0)
- break;
- idx++;
- } /* end while */
- if(found_attr==NULL) {
+ while(H5O_read(ent, H5O_ATTR, idx, &found_attr)!=NULL) {
+ /*
+ * Compare found attribute name to new attribute name reject
+ * creation if names are the same.
+ */
+ if(HDstrcmp(found_attr.name,name)==0) {
+ H5O_reset (H5O_ATTR, &found_attr);
+ found = idx;
+ break;
+ }
+ H5O_reset (H5O_ATTR, &found_attr);
+ idx++;
+ } /* end while */
+ if (found<0) {
HRETURN_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL,
"attribute not found");
- }
+ }
/* Delete the attribute from the location */
- if ((ret_value=H5O_remove(ent, H5O_ATTR, idx)) < 0)
+ if ((ret_value=H5O_remove(ent, H5O_ATTR, found)) < 0)
HRETURN_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL,
"can't delete attribute header message");
@@ -1209,41 +1225,17 @@ H5Adelete(hid_t loc_id, const char *name)
herr_t
H5Aclose(hid_t attr_id)
{
- H5A_t *attr = NULL;
- herr_t ret_value = FAIL;
-
FUNC_ENTER(H5Aclose, FAIL);
/* check arguments */
if (H5_ATTR != H5I_group(attr_id) ||
- (NULL == (attr = H5I_object(attr_id)))) {
+ NULL == H5I_object(attr_id)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute");
}
- /* Check if the attribute has any data yet, if not, fill with zeroes */
- if(!attr->initialized) {
- uint8 *tmp_buf=H5MM_xcalloc(1,attr->data_size);
-
- if (NULL == tmp_buf) {
- HRETURN_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL,
- "can't allocate attribute fill-value");
- }
-
- /* Go write the fill data to the attribute */
- if ((ret_value=H5A_write(attr,attr->dt,tmp_buf))<0) {
- HRETURN_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL,
- "can't write attribute");
- }
-
- /* Free temporary buffer */
- H5MM_xfree(tmp_buf);
- } /* end if */
-
- /* Free the memory used for the attribute */
- H5A_close(attr);
- ret_value=SUCCEED;
-
- FUNC_LEAVE(ret_value);
+ /* Decrement references to that atom (and close it) */
+ H5I_dec_ref (attr_id);
+ FUNC_LEAVE(SUCCEED);
} /* H5Aclose() */
@@ -1320,6 +1312,25 @@ H5A_close(H5A_t *attr)
assert(attr);
+ /* Check if the attribute has any data yet, if not, fill with zeroes */
+ if(attr->ent_opened && !attr->initialized) {
+ uint8 *tmp_buf=H5MM_xcalloc(1,attr->data_size);
+
+ if (NULL == tmp_buf) {
+ HRETURN_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL,
+ "can't allocate attribute fill-value");
+ }
+
+ /* Go write the fill data to the attribute */
+ if (H5A_write(attr,attr->dt,tmp_buf)<0) {
+ HRETURN_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL,
+ "can't write attribute");
+ }
+
+ /* Free temporary buffer */
+ H5MM_xfree(tmp_buf);
+ } /* end if */
+
/* Free dynamicly allocated items */
if(attr->name)
H5MM_xfree(attr->name);
diff --git a/src/H5Apublic.h b/src/H5Apublic.h
index 71322dc..bf62290 100644
--- a/src/H5Apublic.h
+++ b/src/H5Apublic.h
@@ -17,7 +17,7 @@
#define _H5Apublic_H
/* Public headers needed by this file */
-
+#include <H5Ipublic.h>
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5F.c b/src/H5F.c
index 211b54d..7cd2cec 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -153,9 +153,9 @@ H5F_init_interface(void)
H5F_access_dflt.u.mpio.comm = MPI_COMM_SELF;
H5F_access_dflt.u.mpio.info = MPI_INFO_NULL;
#elif (H5F_LOW_DFLT == H5F_LOW_SPLIT)
- /* Nothing to initialize */
+# error "H5F_LOW_SPLIT cannot be a default file driver"
#elif (H5F_LOW_DFLT == H5F_LOW_FAMILY)
- H5F_access_dflt.u.fam.offset_bits = 26u; /*64MB members*/
+# error "H5F_LOW_FAMILY cannot be a default file driver"
#else
# error "Unknown default file driver"
#endif
diff --git a/src/H5Ffamily.c b/src/H5Ffamily.c
index d20a380..10572ce 100644
--- a/src/H5Ffamily.c
+++ b/src/H5Ffamily.c
@@ -100,16 +100,8 @@ H5F_fam_open(const char *name, const H5F_access_t *access_parms,
assert (access_parms);
assert (H5F_LOW_FAMILY==access_parms->driver);
-
- /*
- * Use the default file driver or the specified driver for each of the
- * family members.
- */
- if (access_parms->u.fam.memb_access) {
- memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver);
- } else {
- memb_type = H5F_low_class (H5F_LOW_DFLT);
- }
+ assert (access_parms->u.fam.memb_access);
+ memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver);
/*
* If we're truncating the file then delete all but the first family
@@ -386,14 +378,10 @@ H5F_fam_write(H5F_low_t *lf, const H5F_access_t *access_parms,
assert(buf);
assert (access_parms);
assert (H5F_LOW_FAMILY==access_parms->driver);
+ assert (access_parms->u.fam.memb_access);
/* Get the member driver */
- if (access_parms->u.fam.memb_access) {
- memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver);
- } else {
- memb_type = H5F_low_class (H5F_LOW_DFLT);
- }
-
+ memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver);
member_size = (hsize_t) 1 << lf->u.fam.offset_bits;
membno = H5F_FAM_MEMBNO(addr, lf->u.fam.offset_bits);
offset = H5F_FAM_OFFSET(addr, lf->u.fam.offset_bits);
@@ -564,13 +552,10 @@ H5F_fam_access(const char *name, const H5F_access_t *access_parms,
assert (name && *name);
assert (access_parms);
assert (H5F_LOW_FAMILY==access_parms->driver);
+ assert (access_parms->u.fam.memb_access);
/* Get the driver for the family members */
- if (access_parms->u.fam.memb_access) {
- memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver);
- } else {
- memb_type = H5F_low_class (H5F_LOW_DFLT);
- }
+ memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver);
/* Access the members */
for (membno=0; /*void*/; membno++) {
diff --git a/src/H5Fsplit.c b/src/H5Fsplit.c
new file mode 100644
index 0000000..1359816
--- /dev/null
+++ b/src/H5Fsplit.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 1997 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Thursday, November 13, 1997
+ *
+ * Purpose: A driver that splits the meta data and raw data into two
+ * separate files. The high-order bit of the file address
+ * determines whether the address refers to the meta data file
+ * (high order bit is clear) or the raw data file (high order bit
+ * is set).
+ */
+#include <H5private.h>
+#include <H5Eprivate.h>
+#include <H5Fprivate.h>
+#include <H5MFprivate.h>
+#include <H5MMprivate.h>
+
+/* Default file name extensions */
+#define H5F_SPLIT_META_EXT ".meta"
+#define H5F_SPLIT_RAW_EXT ".raw"
+
+#define PABLO_MASK H5F_split
+static hbool_t interface_initialize_g = FALSE;
+#define INTERFACE_INIT NULL
+
+static hbool_t H5F_split_access(const char *name,
+ const H5F_access_t *access_parms, int mode,
+ H5F_search_t *key/*out*/);
+static H5F_low_t *H5F_split_open(const char *name,
+ const H5F_access_t *access_parms, uintn flags,
+ H5F_search_t *key/*out*/);
+static herr_t H5F_split_close(H5F_low_t *lf, const H5F_access_t *access_parms);
+static herr_t H5F_split_read(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size,
+ uint8 *buf/*out*/);
+static herr_t H5F_split_write(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size,
+ const uint8 *buf);
+static herr_t H5F_split_flush(H5F_low_t *lf, const H5F_access_t *access_parms);
+static herr_t H5F_split_extend(H5F_low_t *lf, const H5F_access_t *access_parms,
+ intn op, hsize_t size, haddr_t *addr/*out*/);
+
+const H5F_low_class_t H5F_LOW_SPLIT_g[1] = {{
+ H5F_split_access, /* access method */
+ H5F_split_open, /* open method */
+ H5F_split_close, /* close method */
+ H5F_split_read, /* read method */
+ H5F_split_write, /* write method */
+ H5F_split_flush, /* flush method */
+ H5F_split_extend, /* extend method */
+}};
+
+/*
+ * This is the bit that determines whether the address is part of the meta
+ * data file or part of the raw data file. Eventually we'll want to pass
+ * this kind of thing down to this function from above...
+ */
+#define H5F_SPLIT_MASK 0x80000000
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_split_open
+ *
+ * Purpose: Opens a split meta data/raw data family with the specified
+ * base name. The name of the meta data file will be created by
+ * appending `.h5' while the name of the raw data file will be
+ * created by appending `.raw'.
+ *
+ * Return: Success: Low-level file pointer
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Monday, November 13, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5F_low_t *
+H5F_split_open(const char *name, const H5F_access_t *access_parms,
+ uintn flags, H5F_search_t *key/*out*/)
+{
+ H5F_low_t *lf = NULL, *ret_value = NULL;
+ char fullname[4096];
+ const char *ext; /*file name extension*/
+ const H5F_low_class_t *meta_type = NULL;
+ const H5F_low_class_t *raw_type = NULL;
+
+ FUNC_ENTER(H5F_split_open, NULL);
+
+ assert(name && *name);
+ assert (access_parms);
+ assert (H5F_LOW_SPLIT==access_parms->driver);
+ assert (access_parms->u.split.meta_access);
+ assert (access_parms->u.split.raw_access);
+
+ /* Get member types */
+ meta_type = H5F_low_class (access_parms->u.split.meta_access->driver);
+ raw_type = H5F_low_class (access_parms->u.split.raw_access->driver);
+
+ /* Create the file descriptor */
+ lf = H5MM_xcalloc(1, sizeof(H5F_low_t));
+ lf->u.split.name = H5MM_xstrdup(name);
+ lf->u.split.mask = H5F_SPLIT_MASK;
+
+ /* Open the meta data file */
+ ext = access_parms->u.split.meta_ext ?
+ access_parms->u.split.meta_ext : H5F_SPLIT_META_EXT;
+ if (strlen (name)+strlen (ext) >= sizeof fullname) {
+ HGOTO_ERROR (H5E_IO, H5E_CANTINIT, NULL, "file name is too long");
+ }
+ strcpy (fullname, name);
+ strcat (fullname, ext);
+
+ lf->u.split.meta = H5F_low_open(meta_type, fullname,
+ access_parms->u.split.meta_access,
+ flags, key/*out*/);
+ if (NULL == lf->u.split.meta) {
+ HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "can't open meta file");
+ }
+
+ /* Open the raw data file */
+ ext = access_parms->u.split.raw_ext ?
+ access_parms->u.split.raw_ext : H5F_SPLIT_RAW_EXT;
+ if (strlen (name)+strlen (ext) >= sizeof fullname) {
+ HGOTO_ERROR (H5E_IO, H5E_CANTINIT, NULL, "file name is too long");
+ }
+ strcpy (fullname, name);
+ strcat (fullname, ext);
+
+ lf->u.split.raw = H5F_low_open(raw_type, fullname,
+ access_parms->u.split.raw_access,
+ flags, NULL);
+ if (NULL == lf->u.split.raw) {
+ HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "can't open raw file");
+ }
+
+ /* Initialize the file size */
+ H5F_low_size(lf->u.split.raw, &(lf->eof));
+ lf->eof.offset |= lf->u.split.mask;
+
+ HRETURN(lf);
+
+ done:
+ if (!ret_value) {
+ if (lf) {
+ H5F_split_close(lf, access_parms);
+ H5MM_xfree(lf);
+ }
+ }
+ FUNC_LEAVE(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_split_close
+ *
+ * Purpose: Closes a split file.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Monday, November 13, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_split_close(H5F_low_t *lf, const H5F_access_t *access_parms)
+{
+ FUNC_ENTER(H5F_split_close, FAIL);
+
+ assert(lf);
+
+ H5F_low_close(lf->u.split.meta, access_parms->u.split.meta_access);
+ H5F_low_close(lf->u.split.raw, access_parms->u.split.raw_access);
+ H5MM_xfree(lf->u.split.name);
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_split_read
+ *
+ * Purpose: Reads a chunk of contiguous data from a split file. We
+ * assume that the data being read never crosses the meta
+ * data/raw data boundary. Reading past the end of a file
+ * returns zeros instead of failing.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Monday, November 13, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_split_read(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size, uint8 *buf/*out*/)
+{
+ haddr_t tmp_addr;
+ H5F_low_t *sub = NULL;
+ herr_t status;
+ const H5F_access_t *sub_parms = NULL;
+
+ FUNC_ENTER(H5F_split_read, FAIL);
+
+ assert(lf);
+ assert(addr && H5F_addr_defined(addr));
+ assert(buf);
+
+ /* Which file to we actually read from? */
+ if (addr->offset & lf->u.split.mask) {
+ sub = lf->u.split.raw;
+ sub_parms = access_parms->u.split.raw_access;
+ tmp_addr.offset = addr->offset & (lf->u.split.mask - 1);
+ } else {
+ sub = lf->u.split.meta;
+ sub_parms = access_parms->u.split.meta_access;
+ tmp_addr = *addr;
+ }
+
+ /* Read the data */
+ status = H5F_low_read(sub, sub_parms, &tmp_addr, size, buf/*out*/);
+ FUNC_LEAVE(status);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_split_write
+ *
+ * Purpose: Writes BUF to either the meta data file or the raw data file.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Monday, November 13, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_split_write(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size, const uint8 *buf)
+{
+ haddr_t tmp_addr;
+ H5F_low_t *sub = NULL;
+ herr_t status;
+ const H5F_access_t *sub_parms = NULL;
+
+ FUNC_ENTER(H5F_split_write, FAIL);
+
+ assert(lf);
+ assert(addr && H5F_addr_defined(addr));
+ assert(buf);
+
+ /* Which file to we actually write to? */
+ if (addr->offset & lf->u.split.mask) {
+ sub = lf->u.split.raw;
+ sub_parms = access_parms->u.split.raw_access;
+ tmp_addr.offset = addr->offset & (lf->u.split.mask - 1);
+ } else {
+ sub = lf->u.split.meta;
+ sub_parms = access_parms->u.split.meta_access;
+ tmp_addr = *addr;
+ }
+
+ /* Write the data */
+ status = H5F_low_write(sub, sub_parms, &tmp_addr, size, buf);
+ FUNC_LEAVE(status);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_split_flush
+ *
+ * Purpose: Flushes all data to disk.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Monday, November 13, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_split_flush(H5F_low_t *lf, const H5F_access_t *access_parms)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER(H5F_split_flush, FAIL);
+
+ assert(lf);
+
+ ret_value = (H5F_low_flush(lf->u.split.meta,
+ access_parms->u.split.meta_access) >= 0 &&
+ H5F_low_flush(lf->u.split.raw,
+ access_parms->u.split.raw_access) >= 0);
+
+ FUNC_LEAVE(ret_value);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_split_access
+ *
+ * Purpose: Determines if both members of the split data file family can
+ * be accessed and returns the key for the first member of the
+ * family.
+ *
+ * Return: Success: TRUE or FALSE
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Monday, November 13, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hbool_t
+H5F_split_access(const char *name, const H5F_access_t *access_parms,
+ int mode, H5F_search_t *key/*out*/)
+{
+ char fullname[4096];
+ hbool_t status;
+ const char *ext; /*file extension*/
+ const H5F_low_class_t *meta_type = NULL;
+ const H5F_low_class_t *raw_type = NULL;
+
+ FUNC_ENTER(H5F_split_access, FAIL);
+
+ assert(name && *name);
+ assert (access_parms);
+ assert (H5F_LOW_SPLIT==access_parms->driver);
+ assert (access_parms->u.split.meta_access);
+ assert (access_parms->u.split.raw_access);
+
+ /* The meta data member */
+ meta_type = H5F_low_class (access_parms->u.split.meta_access->driver);
+ ext = access_parms->u.split.meta_ext ?
+ access_parms->u.split.meta_ext : H5F_SPLIT_META_EXT;
+ if (strlen (name)+strlen (ext) >= sizeof fullname) {
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL, "file name is too long");
+ }
+ strcpy (fullname, name);
+ strcat (fullname, ext);
+
+ status = H5F_low_access(meta_type, fullname,
+ access_parms->u.split.meta_access,
+ mode, key/*out*/);
+ if (status < 0) {
+ HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL,
+ "access call failed for meta data member");
+ }
+ if (!status) HRETURN(FALSE);
+
+ /* The raw data member */
+ raw_type = H5F_low_class (access_parms->u.split.raw_access->driver);
+ ext = access_parms->u.split.raw_ext ?
+ access_parms->u.split.raw_ext : H5F_SPLIT_RAW_EXT;
+ if (strlen (name)+strlen (ext) >= sizeof fullname) {
+ HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL, "file name is too long");
+ }
+ strcpy (fullname, name);
+ strcat (fullname, ext);
+
+ status = H5F_low_access(raw_type, fullname,
+ access_parms->u.split.raw_access,
+ mode, NULL/*out*/);
+ if (status < 0) {
+ HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL,
+ "access call failed for raw data member");
+ }
+ FUNC_LEAVE(status);
+}
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_split_extend
+ *
+ * Purpose: Allocates memory from the end of the meta data file or raw
+ * data file.
+ *
+ * Return: Success: SUCCEED with the address of the allocated
+ * memory returned through the ADDR argument.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 13, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_split_extend(H5F_low_t *lf, const H5F_access_t *access_parms, intn op,
+ hsize_t size, haddr_t *addr/*out*/)
+{
+ FUNC_ENTER(H5F_split_extend, FAIL);
+
+ assert(lf);
+ assert(H5MF_META == op || H5MF_RAW == op);
+ assert(size > 0);
+ assert(addr);
+
+ if (H5MF_META == op) {
+ if (H5F_low_extend(lf->u.split.meta, access_parms->u.split.meta_access,
+ op, size, addr/*out*/)<0) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "meta data allocation failed");
+ }
+ if (addr->offset + size > lf->eof.offset) {
+ lf->eof.offset = addr->offset + size;
+ }
+ } else {
+ if (H5F_low_extend(lf->u.split.raw, access_parms->u.split.raw_access,
+ op, size, addr/*out*/)<0) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "raw data allocation failed");
+ }
+ addr->offset |= lf->u.split.mask;
+ lf->eof = lf->u.split.raw->eof;
+ lf->eof.offset |= lf->u.split.mask;
+ }
+
+ FUNC_LEAVE(SUCCEED);
+}
diff --git a/src/H5I.c b/src/H5I.c
index 6b9383c..defd00a 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -58,7 +58,6 @@ static char RcsId[] = "@(#)$Revision$";
1/7/96 - Finished coding prototype
6/10/97 - Moved into HDF5 library
*/
-
#include <H5private.h>
#include <H5Iprivate.h>
#include <H5Eprivate.h>
diff --git a/src/H5O.c b/src/H5O.c
index 9bf528c..bdf2efd 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -786,7 +786,11 @@ H5O_count (H5G_entry_t *ent, const H5O_class_t *type)
* the null pointer, then this function will malloc() memory
* to hold the result and return its pointer instead.
*
- * Return: Success: Ptr to message in native format.
+ * Return: Success: Ptr to message in native format. The message
+ * should be freed by calling H5O_reset(). If
+ * MESG is a null pointer then the caller should
+ * also call H5MM_xfree() on the return value
+ * after calling H5O_reset().
*
* Failure: NULL
*
diff --git a/src/H5P.c b/src/H5P.c
index b36e80c..fa94d6e 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -1449,8 +1449,8 @@ H5Pset_split (hid_t tid, const char *meta_ext, hid_t meta_tid,
const char *raw_ext, hid_t raw_tid)
{
H5F_access_t *tmpl = NULL;
- H5F_access_t *meta_tmpl = NULL;
- H5F_access_t *raw_tmpl = NULL;
+ H5F_access_t *meta_tmpl = &H5F_access_dflt;
+ H5F_access_t *raw_tmpl = &H5F_access_dflt;
FUNC_ENTER (H5Pset_split, FAIL);
@@ -1462,13 +1462,13 @@ H5Pset_split (hid_t tid, const char *meta_ext, hid_t meta_tid,
}
if (H5P_DEFAULT!=meta_tid &&
(H5P_FILE_ACCESS != H5Pget_class(meta_tid) ||
- NULL == (tmpl = H5I_object(meta_tid)))) {
+ NULL == (meta_tmpl = H5I_object(meta_tid)))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
"not a file access template");
}
if (H5P_DEFAULT!=raw_tid &&
(H5P_FILE_ACCESS != H5Pget_class(raw_tid) ||
- NULL == (tmpl = H5I_object(raw_tid)))) {
+ NULL == (raw_tmpl = H5I_object(raw_tid)))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
"not a file access template");
}
@@ -1498,11 +1498,8 @@ H5Pset_split (hid_t tid, const char *meta_ext, hid_t meta_tid,
* if META_PROPERTIES and/or RAW_PROPERTIES are non-null then
* the file access property list of the meta file and/or raw
* file is copied and its OID returned through these arguments.
- * If the meta file or raw file has no property list then an OID
- * of FAIL (-1) is returned but the H5Pget_split() function
- * still returns SUCCEED. In the future, additional arguments
- * may be added to this function to match those added to
- * H5Pset_sec2().
+ * In the future, additional arguments may be added to this
+ * function to match those added to H5Pset_sec2().
*
* Return: Success: SUCCEED
*
@@ -1556,18 +1553,19 @@ H5Pget_split (hid_t tid, size_t meta_ext_size, char *meta_ext/*out*/,
strncpy (raw_ext, ".raw", raw_ext_size);
}
}
- if (meta_properties && tmpl->u.split.meta_access) {
+ if (meta_properties) {
+ assert (tmpl->u.split.meta_access);
*meta_properties = H5P_create (H5P_FILE_ACCESS,
H5P_copy (H5P_FILE_ACCESS,
tmpl->u.split.meta_access));
}
- if (raw_properties && tmpl->u.split.raw_access) {
+ if (raw_properties) {
+ assert (tmpl->u.split.raw_access);
*raw_properties = H5P_create (H5P_FILE_ACCESS,
H5P_copy (H5P_FILE_ACCESS,
tmpl->u.split.raw_access));
}
-
FUNC_LEAVE (SUCCEED);
}
@@ -1629,12 +1627,9 @@ H5Pset_family (hid_t tid, size_t offset_bits, hid_t memb_tid)
* Purpose: If the file access property list is set to the family driver
* then this function returns zero; otherwise it returns a
* negative value. On success, if MEMB_TID is a non-null
- * pointer it will be initialized with the OID of a copy of the
- * file access template used for the family members. If the
- * family members have no file access template (that is, they
- * are using the default values) then FAIL (-1) is returned for
- * the member property list OID but the function still returns
- * SUCCEED. In the future, additional arguments may be added to
+ * pointer it will be initialized with the id of an open
+ * property list: the file access property list for the family
+ * members. In the future, additional arguments may be added to
* this function to match those added to H5Pset_family().
*
* Return: Success: SUCCEED
@@ -1667,12 +1662,11 @@ H5Pget_family (hid_t tid, size_t *offset_bits/*out*/, hid_t *memb_tid/*out*/)
}
/* Output args */
- if (memb_tid && tmpl->u.fam.memb_access) {
+ if (memb_tid) {
+ assert (tmpl->u.fam.memb_access);
*memb_tid = H5P_create (H5P_FILE_ACCESS,
H5P_copy (H5P_FILE_ACCESS,
tmpl->u.fam.memb_access));
- } else if (memb_tid) {
- *memb_tid = FAIL;
}
if (offset_bits) *offset_bits = tmpl->u.fam.offset_bits;
diff --git a/src/H5T.c b/src/H5T.c
index 1a7f911..4e87d65 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -250,6 +250,34 @@ H5T_init_interface(void)
FUNC_LEAVE(ret_value);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_unlock_cb
+ *
+ * Purpose: Clear the locked flag for a data type. This function is
+ * called when the library is closing in order to unlock all
+ * registered data types and thus make them free-able.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 0
+ *
+ * Programmer: Robb Matzke
+ * Monday, April 27, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static intn
+H5T_unlock_cb (void *dt, const void __unused__ *key)
+{
+ FUNC_ENTER (H5T_unlock_cb, FAIL);
+ assert (dt);
+ ((H5T_t*)dt)->locked = FALSE;
+ FUNC_LEAVE (0);
+}
+
/*--------------------------------------------------------------------------
NAME
H5T_term_interface
@@ -333,33 +361,9 @@ H5T_term_interface(void)
(cfunc)(FAIL, FAIL, pcdata, 0, NULL, NULL);
}
+ /* Unlock all datatypes, then free them */
+ H5I_search (H5_DATATYPE, H5T_unlock_cb, NULL);
H5I_destroy_group(H5_DATATYPE);
- H5T_NATIVE_CHAR_g = FAIL;
- H5T_NATIVE_UCHAR_g = FAIL;
- H5T_NATIVE_SHORT_g = FAIL;
- H5T_NATIVE_USHORT_g = FAIL;
- H5T_NATIVE_INT_g = FAIL;
- H5T_NATIVE_UINT_g = FAIL;
- H5T_NATIVE_LONG_g = FAIL;
- H5T_NATIVE_LLONG_g = FAIL;
- H5T_NATIVE_ULLONG_g = FAIL;
- H5T_NATIVE_HYPER_g = FAIL;
- H5T_NATIVE_UHYPER_g = FAIL;
- H5T_NATIVE_INT8_g = FAIL;
- H5T_NATIVE_UINT8_g = FAIL;
- H5T_NATIVE_INT16_g = FAIL;
- H5T_NATIVE_UINT16_g = FAIL;
- H5T_NATIVE_INT32_g = FAIL;
- H5T_NATIVE_UINT32_g = FAIL;
- H5T_NATIVE_INT64_g = FAIL;
- H5T_NATIVE_UINT64_g = FAIL;
- H5T_NATIVE_ULONG_g = FAIL;
- H5T_NATIVE_FLOAT_g = FAIL;
- H5T_NATIVE_DOUBLE_g = FAIL;
- H5T_NATIVE_TIME_g = FAIL;
- H5T_NATIVE_STRING_g = FAIL;
- H5T_NATIVE_BITFIELD_g = FAIL;
- H5T_NATIVE_OPAQUE_g = FAIL;
}
@@ -2765,6 +2769,7 @@ H5T_close(H5T_t *dt)
if (dt && H5T_COMPOUND == dt->type) {
for (i = 0; i < dt->u.compnd.nmembs; i++) {
H5MM_xfree(dt->u.compnd.memb[i].name);
+ H5T_close (dt->u.compnd.memb[i].type);
}
H5MM_xfree(dt->u.compnd.memb);
H5MM_xfree(dt);