diff options
-rw-r--r-- | src/H5D.c | 50 | ||||
-rw-r--r-- | src/H5Dpublic.h | 1 | ||||
-rw-r--r-- | src/H5Gnode.c | 920 | ||||
-rw-r--r-- | src/H5Gstab.c | 4 | ||||
-rw-r--r-- | src/H5H.c | 16 | ||||
-rw-r--r-- | src/H5P.c | 51 | ||||
-rw-r--r-- | src/H5Pprivate.h | 4 | ||||
-rw-r--r-- | src/H5Ppublic.h | 12 | ||||
-rw-r--r-- | src/H5Psimp.c | 170 | ||||
-rw-r--r-- | test/cmpd_dset.c | 81 | ||||
-rw-r--r-- | test/testhdf5.h | 8 |
11 files changed, 773 insertions, 544 deletions
@@ -38,7 +38,7 @@ struct H5D_t { 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 */ + H5D_create_t create_parms; /*creation parameters */ H5O_layout_t layout; /*data layout */ }; @@ -314,6 +314,54 @@ H5Dclose(hid_t dataset_id) } /*------------------------------------------------------------------------- + * Function: H5Dget_space + * + * Purpose: Returns a copy of the file data space for a dataset. + * + * Return: Success: ID for a copy of the data space. The data + * space should be released by calling + * H5Dclose(). + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Wednesday, January 28, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dget_space (hid_t dataset_id) +{ + H5D_t *dataset = NULL; + H5P_t *copied_space = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER (H5Dget_space, FAIL); + + /* Check args */ + if (H5_DATASET!=H5A_group (dataset_id) || + NULL==(dataset=H5A_object (dataset_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset"); + } + + /* Copy the data space */ + if (NULL==(copied_space=H5P_copy (dataset->space))) { + HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, + "unable to copy the data space"); + } + + /* Create an atom */ + if ((ret_value=H5A_register (H5_DATASPACE, copied_space))<0) { + HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to register data space"); + } + + FUNC_LEAVE (ret_value); +} + +/*------------------------------------------------------------------------- * Function: H5Dread * * Purpose: Reads (part of) a DATASET from the file into application diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index a118725..00847b6 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -39,6 +39,7 @@ hid_t H5Dcreate (hid_t file_id, const char *name, hid_t type_id, hid_t space_id, hid_t create_parms_id); hid_t H5Dopen (hid_t file_id, const char *name); herr_t H5Dclose (hid_t dataset_id); +hid_t H5Dget_space (hid_t dataset_id); herr_t H5Dread (hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t xfer_parms_id, void *buf/*out*/); herr_t H5Dwrite (hid_t dataset_id, hid_t mem_type_id, hid_t mem_space_id, diff --git a/src/H5Gnode.c b/src/H5Gnode.c index be021dd..5eb24d7 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -1,110 +1,110 @@ /*------------------------------------------------------------------------- - * Copyright (C) 1997 National Center for Supercomputing Applications. - * All rights reserved. + * Copyright (C) 1997 National Center for Supercomputing Applications. + * All rights reserved. * *------------------------------------------------------------------------- * - * Created: snode.c - * Jun 26 1997 - * Robb Matzke <matzke@llnl.gov> + * Created: snode.c + * Jun 26 1997 + * Robb Matzke <matzke@llnl.gov> * - * Purpose: Functions for handling symbol table nodes. A - * symbol table node is a small collection of symbol - * table entries. A B-tree usually points to the - * symbol table nodes for any given symbol table. + * Purpose: Functions for handling symbol table nodes. A + * symbol table node is a small collection of symbol + * table entries. A B-tree usually points to the + * symbol table nodes for any given symbol table. * * Modifications: * *------------------------------------------------------------------------- */ -#define H5G_PACKAGE /*suppress error message about including H5Gpkg.h */ +#define H5G_PACKAGE /*suppress error message about including H5Gpkg.h */ /* Packages needed by this file... */ -#include <H5private.h> /*library */ -#include <H5ACprivate.h> /*cache */ -#include <H5Bprivate.h> /*B-link trees */ -#include <H5Eprivate.h> /*error handling */ -#include <H5Gpkg.h> /*me */ -#include <H5Hprivate.h> /*heap */ -#include <H5MFprivate.h> /*file memory management */ -#include <H5MMprivate.h> /*core memory management */ -#include <H5Oprivate.h> /*header messages */ - -#define PABLO_MASK H5G_node_mask +#include <H5private.h> /*library */ +#include <H5ACprivate.h> /*cache */ +#include <H5Bprivate.h> /*B-link trees */ +#include <H5Eprivate.h> /*error handling */ +#include <H5Gpkg.h> /*me */ +#include <H5Hprivate.h> /*heap */ +#include <H5MFprivate.h> /*file memory management */ +#include <H5MMprivate.h> /*core memory management */ +#include <H5Oprivate.h> /*header messages */ + +#define PABLO_MASK H5G_node_mask /* PRIVATE PROTOTYPES */ -static herr_t H5G_node_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, - void *_key); -static herr_t H5G_node_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, - void *_key); -static size_t H5G_node_size(H5F_t *f); -static herr_t H5G_node_create(H5F_t *f, H5B_ins_t op, void *_lt_key, - void *_udata, void *_rt_key, - haddr_t *addr /*out */ ); -static herr_t H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, - H5G_node_t *sym); +static herr_t H5G_node_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, + void *_key); +static herr_t H5G_node_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, + void *_key); +static size_t H5G_node_size(H5F_t *f); +static herr_t H5G_node_create(H5F_t *f, H5B_ins_t op, void *_lt_key, + void *_udata, void *_rt_key, + haddr_t *addr /*out */ ); +static herr_t H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, + H5G_node_t *sym); static H5G_node_t *H5G_node_load(H5F_t *f, const haddr_t *addr, - const void *_udata1, void *_udata2); -static intn H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, - void *_rt_key); -static intn H5G_node_cmp3(H5F_t *f, void *_lt_key, void *_udata, - void *_rt_key); -static herr_t H5G_node_found(H5F_t *f, const haddr_t *addr, - const void *_lt_key, void *_udata, - const void *_rt_key); -static H5B_ins_t H5G_node_insert(H5F_t *f, const haddr_t *addr, - void *_lt_key, hbool_t *lt_key_changed, - void *_md_key, void *_udata, - void *_rt_key, hbool_t *rt_key_changed, - haddr_t *new_node /*out */ ); -static herr_t H5G_node_list(H5F_t *f, const haddr_t *addr, void *_udata); -static size_t H5G_node_sizeof_rkey(H5F_t *f, const void *_udata); + const void *_udata1, void *_udata2); +static intn H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, + void *_rt_key); +static intn H5G_node_cmp3(H5F_t *f, void *_lt_key, void *_udata, + void *_rt_key); +static herr_t H5G_node_found(H5F_t *f, const haddr_t *addr, + const void *_lt_key, void *_udata, + const void *_rt_key); +static H5B_ins_t H5G_node_insert(H5F_t *f, const haddr_t *addr, + void *_lt_key, hbool_t *lt_key_changed, + void *_md_key, void *_udata, + void *_rt_key, hbool_t *rt_key_changed, + haddr_t *new_node /*out */ ); +static herr_t H5G_node_list(H5F_t *f, const haddr_t *addr, void *_udata); +static size_t H5G_node_sizeof_rkey(H5F_t *f, const void *_udata); /* H5G inherits cache-like properties from H5AC */ -const H5AC_class_t H5AC_SNODE[1] = +const H5AC_class_t H5AC_SNODE[1] = { { - H5AC_SNODE_ID, + H5AC_SNODE_ID, (void *(*)(H5F_t *, const haddr_t *, const void *, void *)) H5G_node_load, (herr_t (*)(H5F_t *, hbool_t, const haddr_t *, void *)) H5G_node_flush, }}; /* H5G inherits B-tree like properties from H5B */ -H5B_class_t H5B_SNODE[1] = +H5B_class_t H5B_SNODE[1] = { { - H5B_SNODE_ID, /*id */ - sizeof(H5G_node_key_t), /*sizeof_nkey */ - H5G_node_sizeof_rkey, /*get_sizeof_rkey */ - H5G_node_create, /*new */ - H5G_node_cmp2, /*cmp2 */ - H5G_node_cmp3, /*cmp3 */ - H5G_node_found, /*found */ - H5G_node_insert, /*insert */ - TRUE, /*follow min branch? */ - TRUE, /*follow max branch? */ - H5G_node_list, /*list */ - H5G_node_decode_key, /*decode */ - H5G_node_encode_key, /*encode */ + H5B_SNODE_ID, /*id */ + sizeof(H5G_node_key_t), /*sizeof_nkey */ + H5G_node_sizeof_rkey, /*get_sizeof_rkey */ + H5G_node_create, /*new */ + H5G_node_cmp2, /*cmp2 */ + H5G_node_cmp3, /*cmp3 */ + H5G_node_found, /*found */ + H5G_node_insert, /*insert */ + TRUE, /*follow min branch? */ + TRUE, /*follow max branch? */ + H5G_node_list, /*list */ + H5G_node_decode_key, /*decode */ + H5G_node_encode_key, /*encode */ }}; /* Interface initialization */ -static intn interface_initialize_g = FALSE; -#define INTERFACE_INIT NULL +static intn interface_initialize_g = FALSE; +#define INTERFACE_INIT NULL /*------------------------------------------------------------------------- - * Function: H5G_node_sizeof_rkey + * Function: H5G_node_sizeof_rkey * - * Purpose: Returns the size of a raw B-link tree key for the specified - * file. + * Purpose: Returns the size of a raw B-link tree key for the specified + * file. * - * Return: Success: Size of the key. + * Return: Success: Size of the key. * - * Failure: never fails + * Failure: never fails * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 14 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 14 1997 * * Modifications: * @@ -113,21 +113,21 @@ static intn interface_initialize_g = FALSE; static size_t H5G_node_sizeof_rkey(H5F_t *f, const void *udata __attribute__((unused))) { - return H5F_SIZEOF_SIZE(f); /*the name offset */ + return H5F_SIZEOF_SIZE(f); /*the name offset */ } /*------------------------------------------------------------------------- - * Function: H5G_node_decode_key + * Function: H5G_node_decode_key * - * Purpose: Decodes a raw key into a native key. + * Purpose: Decodes a raw key into a native key. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 8 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 8 1997 * * Modifications: * @@ -136,7 +136,7 @@ H5G_node_sizeof_rkey(H5F_t *f, const void *udata __attribute__((unused))) static herr_t H5G_node_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) { - H5G_node_key_t *key = (H5G_node_key_t *) _key; + H5G_node_key_t *key = (H5G_node_key_t *) _key; FUNC_ENTER(H5G_node_decode_key, FAIL); @@ -150,17 +150,17 @@ H5G_node_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) } /*------------------------------------------------------------------------- - * Function: H5G_node_encode_key + * Function: H5G_node_encode_key * - * Purpose: Encodes a native key into a raw key. + * Purpose: Encodes a native key into a raw key. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 8 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 8 1997 * * Modifications: * @@ -169,7 +169,7 @@ H5G_node_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) static herr_t H5G_node_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) { - H5G_node_key_t *key = (H5G_node_key_t *) _key; + H5G_node_key_t *key = (H5G_node_key_t *) _key; FUNC_ENTER(H5G_node_encode_key, FAIL); @@ -183,17 +183,17 @@ H5G_node_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) } /*------------------------------------------------------------------------- - * Function: H5G_node_size + * Function: H5G_node_size * - * Purpose: Returns the total size of a symbol table node. + * Purpose: Returns the total size of a symbol table node. * - * Return: Success: Total size of the node in bytes. + * Return: Success: Total size of the node in bytes. * - * Failure: Never fails. + * Failure: Never fails. * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -203,25 +203,25 @@ static size_t H5G_node_size(H5F_t *f) { return H5G_NODE_SIZEOF_HDR(f) + - (2 * H5G_NODE_K(f)) * H5G_SIZEOF_ENTRY(f); + (2 * H5G_NODE_K(f)) * H5G_SIZEOF_ENTRY(f); } /*------------------------------------------------------------------------- - * Function: H5G_node_create + * Function: H5G_node_create * - * Purpose: Creates a new empty symbol table node. This function is - * called by the B-tree insert function for an empty tree. It - * is also called internally to split a symbol node with LT_KEY - * and RT_KEY null pointers. + * Purpose: Creates a new empty symbol table node. This function is + * called by the B-tree insert function for an empty tree. It + * is also called internally to split a symbol node with LT_KEY + * and RT_KEY null pointers. * - * Return: Success: SUCCEED. The address of symbol table node is - * returned through the ADDR argument. + * Return: Success: SUCCEED. The address of symbol table node is + * returned through the ADDR argument. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -229,13 +229,13 @@ H5G_node_size(H5F_t *f) */ static herr_t H5G_node_create(H5F_t *f, H5B_ins_t op, - void *_lt_key, void *_udata, void *_rt_key, - haddr_t *addr /*out */ ) + void *_lt_key, void *_udata, void *_rt_key, + haddr_t *addr /*out */ ) { - H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; - H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; - H5G_node_t *sym = NULL; - size_t size = 0; + H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; + H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; + H5G_node_t *sym = NULL; + size_t size = 0; FUNC_ENTER(H5G_node_create, FAIL); @@ -248,17 +248,17 @@ H5G_node_create(H5F_t *f, H5B_ins_t op, sym = H5MM_xcalloc(1, sizeof(H5G_node_t)); size = H5G_node_size(f); if (H5MF_alloc(f, H5MF_META, size, addr /*out */ ) < 0) { - H5MM_xfree(sym); - HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, - "unable to allocate file space"); + H5MM_xfree(sym); + HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, + "unable to allocate file space"); } sym->dirty = TRUE; sym->entry = H5MM_xcalloc(2 * H5G_NODE_K(f), sizeof(H5G_entry_t)); if (H5AC_set(f, H5AC_SNODE, addr, sym) < 0) { - H5MM_xfree(sym->entry); - H5MM_xfree(sym); - HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, - "unable to cache symbol table leaf node"); + H5MM_xfree(sym->entry); + H5MM_xfree(sym); + HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, + "unable to cache symbol table leaf node"); } /* * The left and right symbols in an empty tree are both the @@ -267,25 +267,25 @@ H5G_node_create(H5F_t *f, H5B_ins_t op, * that there are no symbols. */ if (lt_key) - lt_key->offset = 0; + lt_key->offset = 0; if (rt_key) - rt_key->offset = 0; + rt_key->offset = 0; FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5G_node_flush + * Function: H5G_node_flush * - * Purpose: Flush a symbol table node to disk. + * Purpose: Flush a symbol table node to disk. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -293,12 +293,12 @@ H5G_node_create(H5F_t *f, H5B_ins_t op, */ static herr_t H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, - H5G_node_t *sym) + H5G_node_t *sym) { - uint8 *buf = NULL, *p = NULL; - size_t size; - herr_t status; - int i; + uint8 *buf = NULL, *p = NULL; + size_t size; + herr_t status; + int i; FUNC_ENTER(H5G_node_flush, FAIL); @@ -313,64 +313,64 @@ H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, * Look for dirty entries and set the node dirty flag. */ for (i = 0; i < sym->nsyms; i++) { - if (sym->entry[i].dirty) - sym->dirty = TRUE; + if (sym->entry[i].dirty) + sym->dirty = TRUE; } /* * Write the symbol node to disk. */ if (sym->dirty) { - size = H5G_node_size(f); - buf = p = H5MM_xmalloc(size); + size = H5G_node_size(f); + buf = p = H5MM_xmalloc(size); - /* magic number */ - HDmemcpy(p, H5G_NODE_MAGIC, H5G_NODE_SIZEOF_MAGIC); - p += 4; + /* magic number */ + HDmemcpy(p, H5G_NODE_MAGIC, H5G_NODE_SIZEOF_MAGIC); + p += 4; - /* version number */ - *p++ = H5G_NODE_VERS; + /* version number */ + *p++ = H5G_NODE_VERS; - /* reserved */ - *p++ = 0; + /* reserved */ + *p++ = 0; - /* number of symbols */ - UINT16ENCODE(p, sym->nsyms); + /* number of symbols */ + UINT16ENCODE(p, sym->nsyms); - /* entries */ - H5G_ent_encode_vec(f, &p, sym->entry, sym->nsyms); - HDmemset(p, 0, size - (p - buf)); + /* entries */ + H5G_ent_encode_vec(f, &p, sym->entry, sym->nsyms); + HDmemset(p, 0, size - (p - buf)); - status = H5F_block_write(f, addr, size, buf); - buf = H5MM_xfree(buf); - if (status < 0) - HRETURN_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, - "unable to write symbol table node to " - "the file"); + status = H5F_block_write(f, addr, size, buf); + buf = H5MM_xfree(buf); + if (status < 0) + HRETURN_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, + "unable to write symbol table node to " + "the file"); } /* - * Destroy the symbol node? This might happen if the node is being + * Destroy the symbol node? This might happen if the node is being * preempted from the cache. */ if (destroy) { - sym->entry = H5MM_xfree(sym->entry); - H5MM_xfree(sym); + sym->entry = H5MM_xfree(sym->entry); + H5MM_xfree(sym); } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5G_node_load + * Function: H5G_node_load * - * Purpose: Loads a symbol table node from the file. + * Purpose: Loads a symbol table node from the file. * - * Return: Success: Ptr to the new table. + * Return: Success: Ptr to the new table. * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -378,13 +378,13 @@ H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, */ static H5G_node_t * H5G_node_load(H5F_t *f, const haddr_t *addr, const void *_udata1, - void *_udata2) + void *_udata2) { - H5G_node_t *sym = NULL; - size_t size = 0; - uint8 *buf = NULL; - const uint8 *p = NULL; - H5G_node_t *ret_value = NULL; /*for error handling */ + H5G_node_t *sym = NULL; + size_t size = 0; + uint8 *buf = NULL; + const uint8 *p = NULL; + H5G_node_t *ret_value = NULL; /*for error handling */ FUNC_ENTER(H5G_node_load, NULL); @@ -405,20 +405,20 @@ H5G_node_load(H5F_t *f, const haddr_t *addr, const void *_udata1, sym->entry = H5MM_xcalloc(2 * H5G_NODE_K(f), sizeof(H5G_entry_t)); if (H5F_block_read(f, addr, size, buf) < 0) { - HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, - "unabel to read symbol table node"); + HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, + "unabel to read symbol table node"); } /* magic */ if (HDmemcmp(p, H5G_NODE_MAGIC, H5G_NODE_SIZEOF_MAGIC)) { - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, - "bad symbol table node signature"); + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, + "bad symbol table node signature"); } p += 4; /* version */ if (H5G_NODE_VERS != *p++) { - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, - "bad symbol table node version"); + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, + "bad symbol table node version"); } /* reserved */ p++; @@ -428,8 +428,8 @@ H5G_node_load(H5F_t *f, const haddr_t *addr, const void *_udata1, /* entries */ if (H5G_ent_decode_vec(f, &p, sym->entry, sym->nsyms) < 0) { - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, - "unable to decode symbol table entries"); + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, + "unable to decode symbol table entries"); } buf = H5MM_xfree(buf); @@ -437,33 +437,33 @@ H5G_node_load(H5F_t *f, const haddr_t *addr, const void *_udata1, done: if (!ret_value) { - buf = H5MM_xfree(buf); - if (sym) { - sym->entry = H5MM_xfree(sym->entry); - sym = H5MM_xfree(sym); - } + buf = H5MM_xfree(buf); + if (sym) { + sym->entry = H5MM_xfree(sym->entry); + sym = H5MM_xfree(sym); + } } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5G_node_cmp2 + * Function: H5G_node_cmp2 * - * Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY). - * The UDATA pointer supplies extra data not contained in the - * keys (in this case, the heap address). + * Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY). + * The UDATA pointer supplies extra data not contained in the + * keys (in this case, the heap address). * - * Return: Success: negative if LT_KEY is less than RT_KEY. + * Return: Success: negative if LT_KEY is less than RT_KEY. * - * positive if LT_KEY is greater than RT_KEY. + * positive if LT_KEY is greater than RT_KEY. * - * zero if LT_KEY and RT_KEY are equal. + * zero if LT_KEY and RT_KEY are equal. * - * Failure: FAIL (same as LT_KEY<RT_KEY) + * Failure: FAIL (same as LT_KEY<RT_KEY) * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -472,11 +472,11 @@ H5G_node_load(H5F_t *f, const haddr_t *addr, const void *_udata1, static intn H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key) { - H5G_bt_ud1_t *udata = (H5G_bt_ud1_t *) _udata; - H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; - H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; - const char *s1, *s2; - intn cmp; + H5G_bt_ud1_t *udata = (H5G_bt_ud1_t *) _udata; + H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; + H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; + const char *s1, *s2; + intn cmp; FUNC_ENTER(H5G_node_cmp2, FAIL); @@ -485,12 +485,12 @@ H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key) assert(rt_key); if (NULL == (s1 = H5H_peek(f, &(udata->heap_addr), lt_key->offset))) { - HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, - "unable to read symbol name"); + HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, + "unable to read symbol name"); } if (NULL == (s2 = H5H_peek(f, &(udata->heap_addr), rt_key->offset))) { - HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, - "unable to read symbol name"); + HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, + "unable to read symbol name"); } cmp = HDstrcmp(s1, s2); @@ -498,27 +498,27 @@ H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key) } /*------------------------------------------------------------------------- - * Function: H5G_node_cmp3 + * Function: H5G_node_cmp3 * - * Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY) - * against another key (not necessarily the same type) - * pointed to by UDATA. + * Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY) + * against another key (not necessarily the same type) + * pointed to by UDATA. * - * Return: Success: negative if the UDATA key is less than - * or equal to the LT_KEY + * Return: Success: negative if the UDATA key is less than + * or equal to the LT_KEY * - * positive if the UDATA key is greater - * than the RT_KEY. + * positive if the UDATA key is greater + * than the RT_KEY. * - * zero if the UDATA key falls between - * the LT_KEY (exclusive) and the - * RT_KEY (inclusive). + * zero if the UDATA key falls between + * the LT_KEY (exclusive) and the + * RT_KEY (inclusive). * - * Failure: FAIL (same as UDATA < LT_KEY) + * Failure: FAIL (same as UDATA < LT_KEY) * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -527,55 +527,55 @@ H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key) static intn H5G_node_cmp3(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key) { - H5G_bt_ud1_t *udata = (H5G_bt_ud1_t *) _udata; - H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; - H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; - const char *s; + H5G_bt_ud1_t *udata = (H5G_bt_ud1_t *) _udata; + H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; + H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; + const char *s; FUNC_ENTER(H5G_node_cmp3, FAIL); /* left side */ if (NULL == (s = H5H_peek(f, &(udata->heap_addr), lt_key->offset))) { - HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, - "unable to read symbol name"); + HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, + "unable to read symbol name"); } if (HDstrcmp(udata->name, s) <= 0) - HRETURN(-1); + HRETURN(-1); /* right side */ if (NULL == (s = H5H_peek(f, &(udata->heap_addr), rt_key->offset))) { - HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, - "unable to read symbol name"); + HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, + "unable to read symbol name"); } if (HDstrcmp(udata->name, s) > 0) - HRETURN(1); + HRETURN(1); FUNC_LEAVE(0); } /*------------------------------------------------------------------------- - * Function: H5G_node_found + * Function: H5G_node_found * - * Purpose: The B-tree search engine has found the symbol table node - * which contains the requested symbol if the symbol exists. - * This function should examine that node for the symbol and - * return information about the symbol through the UDATA - * structure which contains the symbol name on function - * entry. + * Purpose: The B-tree search engine has found the symbol table node + * which contains the requested symbol if the symbol exists. + * This function should examine that node for the symbol and + * return information about the symbol through the UDATA + * structure which contains the symbol name on function + * entry. * - * If the operation flag in UDATA is H5G_OPER_FIND, then - * the entry is copied from the symbol table to the UDATA - * entry field. Otherwise the entry is copied from the - * UDATA entry field to the symbol table. + * If the operation flag in UDATA is H5G_OPER_FIND, then + * the entry is copied from the symbol table to the UDATA + * entry field. Otherwise the entry is copied from the + * UDATA entry field to the symbol table. * - * Return: Success: SUCCEED if found and data returned through - * the UDATA pointer. + * Return: Success: SUCCEED if found and data returned through + * the UDATA pointer. * - * Failure: FAIL if not found. + * Failure: FAIL if not found. * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -583,13 +583,13 @@ H5G_node_cmp3(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key) */ static herr_t H5G_node_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, - void *_udata, const void *_rt_key) + void *_udata, const void *_rt_key) { - H5G_bt_ud1_t *bt_udata = (H5G_bt_ud1_t *) _udata; - H5G_node_t *sn = NULL; - intn lt = 0, idx = 0, rt, cmp = 1; - const char *s; - herr_t ret_value = FAIL; + H5G_bt_ud1_t *bt_udata = (H5G_bt_ud1_t *) _udata; + H5G_node_t *sn = NULL; + intn lt = 0, idx = 0, rt, cmp = 1; + const char *s; + herr_t ret_value = FAIL; FUNC_ENTER(H5G_node_found, FAIL); @@ -604,86 +604,86 @@ H5G_node_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, * Load the symbol table node for exclusive access. */ if (NULL == (sn = H5AC_protect(f, H5AC_SNODE, addr, NULL, NULL))) { - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, - "unable to protect symbol table node"); + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, + "unable to protect symbol table node"); } /* * Binary search. */ rt = sn->nsyms; while (lt < rt && cmp) { - idx = (lt + rt) / 2; - if (NULL == (s = H5H_peek(f, &(bt_udata->heap_addr), - sn->entry[idx].name_off))) { - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, - "unable to read symbol name"); - } - cmp = HDstrcmp(bt_udata->name, s); - - if (cmp < 0) { - rt = idx; - } else { - lt = idx + 1; - } + idx = (lt + rt) / 2; + if (NULL == (s = H5H_peek(f, &(bt_udata->heap_addr), + sn->entry[idx].name_off))) { + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, + "unable to read symbol name"); + } + cmp = HDstrcmp(bt_udata->name, s); + + if (cmp < 0) { + rt = idx; + } else { + lt = idx + 1; + } } if (cmp) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found"); + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found"); switch (bt_udata->operation) { case H5G_OPER_FIND: - /* - * The caller is querying the symbol entry. Return just a pointer to - * the entry. The pointer is valid until the next call to H5AC. - */ - bt_udata->ent = sn->entry[idx]; - break; + /* + * The caller is querying the symbol entry. Return just a pointer to + * the entry. The pointer is valid until the next call to H5AC. + */ + bt_udata->ent = sn->entry[idx]; + break; default: - HRETURN_ERROR(H5E_SYM, H5E_UNSUPPORTED, FAIL, - "internal erorr (unknown symbol find operation)"); - break; + HRETURN_ERROR(H5E_SYM, H5E_UNSUPPORTED, FAIL, + "internal erorr (unknown symbol find operation)"); + break; } ret_value = SUCCEED; done: if (sn && H5AC_unprotect(f, H5AC_SNODE, addr, sn) < 0) { - HRETURN_ERROR(H5E_SYM, H5E_PROTECT, FAIL, - "unable to release symbol table node"); + HRETURN_ERROR(H5E_SYM, H5E_PROTECT, FAIL, + "unable to release symbol table node"); } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5G_node_insert + * Function: H5G_node_insert * - * Purpose: The B-tree insertion engine has found the symbol table node - * which should receive the new symbol/address pair. This - * function adds it to that node unless it already existed. + * Purpose: The B-tree insertion engine has found the symbol table node + * which should receive the new symbol/address pair. This + * function adds it to that node unless it already existed. * - * If the node has no room for the symbol then the node is - * split into two nodes. The original node contains the - * low values and the new node contains the high values. - * The new symbol table entry is added to either node as - * appropriate. When a split occurs, this function will - * write the maximum key of the low node to the MID buffer - * and return the address of the new node. + * If the node has no room for the symbol then the node is + * split into two nodes. The original node contains the + * low values and the new node contains the high values. + * The new symbol table entry is added to either node as + * appropriate. When a split occurs, this function will + * write the maximum key of the low node to the MID buffer + * and return the address of the new node. * - * If the new key is larger than RIGHT then update RIGHT - * with the new key. + * If the new key is larger than RIGHT then update RIGHT + * with the new key. * - * Return: Success: An insertion command for the caller, one of - * the H5B_INS_* constants. The address of the - * new node, if any, is returned through the - * NEW_NODE argument. NEW_NODE might not be - * initialized if the return value is - * H5B_INS_NOOP. + * Return: Success: An insertion command for the caller, one of + * the H5B_INS_* constants. The address of the + * new node, if any, is returned through the + * NEW_NODE argument. NEW_NODE might not be + * initialized if the return value is + * H5B_INS_NOOP. * - * Failure: H5B_INS_ERROR, NEW_NODE might not be - * initialized. + * Failure: H5B_INS_ERROR, NEW_NODE might not be + * initialized. * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 24 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 24 1997 * * Modifications: * @@ -691,23 +691,23 @@ H5G_node_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, */ static H5B_ins_t H5G_node_insert(H5F_t *f, const haddr_t *addr, - void *_lt_key, hbool_t *lt_key_changed, - void *_md_key, void *_udata, - void *_rt_key, hbool_t *rt_key_changed, - haddr_t *new_node) + void *_lt_key, hbool_t *lt_key_changed, + void *_md_key, void *_udata, + void *_rt_key, hbool_t *rt_key_changed, + haddr_t *new_node) { - H5G_node_key_t *md_key = (H5G_node_key_t *) _md_key; - H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; - H5G_bt_ud1_t *bt_udata = (H5G_bt_ud1_t *) _udata; - - H5G_node_t *sn = NULL, *snrt = NULL; - size_t offset; /*offset of name in heap */ - const char *s; - intn idx = -1, cmp = 1; - intn lt = 0, rt; /*binary search cntrs */ - H5B_ins_t ret_value = H5B_INS_ERROR; - H5G_node_t *insert_into = NULL; /*node that gets new entry */ - haddr_t insert_addr; /*address of that node */ + H5G_node_key_t *md_key = (H5G_node_key_t *) _md_key; + H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; + H5G_bt_ud1_t *bt_udata = (H5G_bt_ud1_t *) _udata; + + H5G_node_t *sn = NULL, *snrt = NULL; + size_t offset; /*offset of name in heap */ + const char *s; + intn idx = -1, cmp = 1; + intn lt = 0, rt; /*binary search cntrs */ + H5B_ins_t ret_value = H5B_INS_ERROR; + H5G_node_t *insert_into = NULL; /*node that gets new entry*/ + haddr_t insert_addr; /*address of that node */ FUNC_ENTER(H5G_node_insert, H5B_INS_ERROR); @@ -725,30 +725,30 @@ H5G_node_insert(H5F_t *f, const haddr_t *addr, * Load the symbol node. */ if (NULL == (sn = H5AC_protect(f, H5AC_SNODE, addr, NULL, NULL))) { - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, - "unable to protect symbol table node"); + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, + "unable to protect symbol table node"); } /* - * Where does the new symbol get inserted? We use a binary search. + * Where does the new symbol get inserted? We use a binary search. */ rt = sn->nsyms; while (lt < rt) { - idx = (lt + rt) / 2; - if (NULL == (s = H5H_peek(f, &(bt_udata->heap_addr), - sn->entry[idx].name_off))) { - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, - "unable to read symbol name"); - } - if (0 == (cmp = HDstrcmp(bt_udata->name, s))) { - /*already present */ - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, - "symbol is already present in symbol table"); - } - if (cmp < 0) { - rt = idx; - } else { - lt = idx + 1; - } + idx = (lt + rt) / 2; + if (NULL == (s = H5H_peek(f, &(bt_udata->heap_addr), + sn->entry[idx].name_off))) { + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, + "unable to read symbol name"); + } + if (0 == (cmp = HDstrcmp(bt_udata->name, s))) { + /*already present */ + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, + "symbol is already present in symbol table"); + } + if (cmp < 0) { + rt = idx; + } else { + lt = idx + 1; + } } idx += cmp > 0 ? 1 : 0; @@ -756,97 +756,97 @@ H5G_node_insert(H5F_t *f, const haddr_t *addr, * Add the new name to the heap. */ offset = H5H_insert(f, &(bt_udata->heap_addr), HDstrlen(bt_udata->name)+1, - bt_udata->name); + bt_udata->name); bt_udata->ent.name_off = offset; if (offset <= 0) { - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, - "unable to insert symbol name into heap"); + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, + "unable to insert symbol name into heap"); } if (sn->nsyms >= 2 * H5G_NODE_K(f)) { - /* - * The node is full. Split it into a left and right - * node and return the address of the new right node (the - * left node is at the same address as the original node). - */ - ret_value = H5B_INS_RIGHT; - - /* The right node */ - if (H5G_node_create(f, H5B_INS_FIRST, NULL, NULL, NULL, - new_node /*out */ ) < 0) { - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, - "unable to split symbol table node"); - } - if (NULL == (snrt = H5AC_find(f, H5AC_SNODE, new_node, NULL, NULL))) { - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, - "unable to split symbol table node"); - } - HDmemcpy(snrt->entry, sn->entry + H5G_NODE_K(f), - H5G_NODE_K(f) * sizeof(H5G_entry_t)); - snrt->nsyms = H5G_NODE_K(f); - snrt->dirty = TRUE; - - /* The left node */ - HDmemset(sn->entry + H5G_NODE_K(f), 0, - H5G_NODE_K(f) * sizeof(H5G_entry_t)); - sn->nsyms = H5G_NODE_K(f); - sn->dirty = TRUE; - - /* The middle key */ - md_key->offset = sn->entry[sn->nsyms - 1].name_off; - - /* Where to insert the new entry? */ - if (idx <= H5G_NODE_K(f)) { - insert_into = sn; - insert_addr = *addr; - if (idx == H5G_NODE_K(f)) - md_key->offset = offset; - } else { - idx -= H5G_NODE_K(f); - insert_into = snrt; - insert_addr = *new_node; - } + /* + * The node is full. Split it into a left and right + * node and return the address of the new right node (the + * left node is at the same address as the original node). + */ + ret_value = H5B_INS_RIGHT; + + /* The right node */ + if (H5G_node_create(f, H5B_INS_FIRST, NULL, NULL, NULL, + new_node /*out */ ) < 0) { + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, + "unable to split symbol table node"); + } + if (NULL == (snrt = H5AC_find(f, H5AC_SNODE, new_node, NULL, NULL))) { + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, + "unable to split symbol table node"); + } + HDmemcpy(snrt->entry, sn->entry + H5G_NODE_K(f), + H5G_NODE_K(f) * sizeof(H5G_entry_t)); + snrt->nsyms = H5G_NODE_K(f); + snrt->dirty = TRUE; + + /* The left node */ + HDmemset(sn->entry + H5G_NODE_K(f), 0, + H5G_NODE_K(f) * sizeof(H5G_entry_t)); + sn->nsyms = H5G_NODE_K(f); + sn->dirty = TRUE; + + /* The middle key */ + md_key->offset = sn->entry[sn->nsyms - 1].name_off; + + /* Where to insert the new entry? */ + if (idx <= H5G_NODE_K(f)) { + insert_into = sn; + insert_addr = *addr; + if (idx == H5G_NODE_K(f)) + md_key->offset = offset; + } else { + idx -= H5G_NODE_K(f); + insert_into = snrt; + insert_addr = *new_node; + } } else { - /* Where to insert the new entry? */ - ret_value = H5B_INS_NOOP; - sn->dirty = TRUE; - insert_into = sn; - insert_addr = *addr; - if (idx == sn->nsyms) { - rt_key->offset = offset; - *rt_key_changed = TRUE; - } + /* Where to insert the new entry? */ + ret_value = H5B_INS_NOOP; + sn->dirty = TRUE; + insert_into = sn; + insert_addr = *addr; + if (idx == sn->nsyms) { + rt_key->offset = offset; + *rt_key_changed = TRUE; + } } /* Move entries */ HDmemmove(insert_into->entry + idx + 1, - insert_into->entry + idx, - (insert_into->nsyms - idx) * sizeof(H5G_entry_t)); + insert_into->entry + idx, + (insert_into->nsyms - idx) * sizeof(H5G_entry_t)); insert_into->entry[idx] = bt_udata->ent; insert_into->entry[idx].dirty = TRUE; insert_into->nsyms += 1; done: if (sn && H5AC_unprotect(f, H5AC_SNODE, addr, sn) < 0) { - HRETURN_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, - "unable to release symbol table node"); + HRETURN_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, + "unable to release symbol table node"); } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5G_node_list + * Function: H5G_node_list * - * Purpose: This function gets called during a group list operation. - * It should fill in data in the UDATA struct. + * Purpose: This function gets called during a group list operation. + * It should fill in data in the UDATA struct. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 24 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 24 1997 * * Modifications: * @@ -855,11 +855,11 @@ H5G_node_insert(H5F_t *f, const haddr_t *addr, static herr_t H5G_node_list(H5F_t *f, const haddr_t *addr, void *_udata) { - H5G_bt_ud2_t *bt_udata = (H5G_bt_ud2_t *) _udata; - H5G_node_t *sn = NULL; - intn i; - const char *s; - herr_t ret_value = FAIL; + H5G_bt_ud2_t *bt_udata = (H5G_bt_ud2_t *) _udata; + H5G_node_t *sn = NULL; + intn i; + const char *s; + herr_t ret_value = FAIL; FUNC_ENTER(H5G_node_list, FAIL); @@ -871,8 +871,8 @@ H5G_node_list(H5F_t *f, const haddr_t *addr, void *_udata) assert(bt_udata); if (NULL == (sn = H5AC_protect(f, H5AC_SNODE, addr, NULL, NULL))) { - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, - "unable to protect symbol table node"); + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, + "unable to protect symbol table node"); } /* * If we've already overflowed the user-supplied buffer, then just @@ -880,26 +880,26 @@ H5G_node_list(H5F_t *f, const haddr_t *addr, void *_udata) * anything else. */ if (bt_udata->nsyms >= bt_udata->maxentries) { - bt_udata->nsyms += sn->nsyms; - HGOTO_DONE(SUCCEED); + bt_udata->nsyms += sn->nsyms; + HGOTO_DONE(SUCCEED); } /* * Save the symbol table entries. */ if (bt_udata->entry) { - for (i = 0; i < sn->nsyms && bt_udata->nsyms + i < bt_udata->maxentries; i++) { - bt_udata->entry[bt_udata->nsyms + i] = sn->entry[i]; - } + for (i = 0; i < sn->nsyms && bt_udata->nsyms + i < bt_udata->maxentries; i++) { + bt_udata->entry[bt_udata->nsyms + i] = sn->entry[i]; + } } if (bt_udata->name) { - for (i = 0; i < sn->nsyms && bt_udata->nsyms + i < bt_udata->maxentries; i++) { - if (NULL == (s = H5H_peek(f, &(bt_udata->heap_addr), - sn->entry[i].name_off))) { - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, - "unable to read symbol name"); - } - bt_udata->name[bt_udata->nsyms + i] = H5MM_xstrdup(s); - } + for (i = 0; i < sn->nsyms && bt_udata->nsyms + i < bt_udata->maxentries; i++) { + if (NULL == (s = H5H_peek(f, &(bt_udata->heap_addr), + sn->entry[i].name_off))) { + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, + "unable to read symbol name"); + } + bt_udata->name[bt_udata->nsyms + i] = H5MM_xstrdup(s); + } } /* * Update the number of symbols. @@ -909,25 +909,25 @@ H5G_node_list(H5F_t *f, const haddr_t *addr, void *_udata) done: if (sn && H5AC_unprotect(f, H5AC_SNODE, addr, sn) < 0) { - HRETURN_ERROR(H5E_CACHE, H5E_PROTECT, FAIL, - "unable to release symbol table node"); + HRETURN_ERROR(H5E_CACHE, H5E_PROTECT, FAIL, + "unable to release symbol table node"); } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5G_node_debug + * Function: H5G_node_debug * - * Purpose: Prints debugging information about a symbol table node - * or a B-tree node for a symbol table B-tree. + * Purpose: Prints debugging information about a symbol table node + * or a B-tree node for a symbol table B-tree. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 4 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 4 1997 * * Modifications: * @@ -935,12 +935,12 @@ H5G_node_list(H5F_t *f, const haddr_t *addr, void *_udata) */ herr_t H5G_node_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, - intn fwidth, const haddr_t *heap) + intn fwidth, const haddr_t *heap) { - int i; - H5G_node_t *sn = NULL; - herr_t status; - const char *s; + int i; + H5G_node_t *sn = NULL; + herr_t status; + const char *s; FUNC_ENTER(H5G_node_debug, FAIL); @@ -958,33 +958,33 @@ H5G_node_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, * B-tree node. */ if (NULL == (sn = H5AC_protect(f, H5AC_SNODE, addr, NULL, NULL))) { - H5ECLEAR; /*discard that error */ - status = H5B_debug(f, addr, stream, indent, fwidth, H5B_SNODE, NULL); - if (status < 0) { - HRETURN_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, - "unable to debug B-tree node"); - } - HRETURN(SUCCEED); + H5ECLEAR; /*discard that error */ + status = H5B_debug(f, addr, stream, indent, fwidth, H5B_SNODE, NULL); + if (status < 0) { + HRETURN_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, + "unable to debug B-tree node"); + } + HRETURN(SUCCEED); } fprintf(stream, "%*sSymbol Table Node...\n", indent, ""); fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, - "Dirty:", - sn->dirty ? "Yes" : "No"); + "Dirty:", + sn->dirty ? "Yes" : "No"); fprintf(stream, "%*s%-*s %d of %d\n", indent, "", fwidth, - "Number of Symbols:", - sn->nsyms, 2 * H5G_NODE_K(f)); + "Number of Symbols:", + sn->nsyms, 2 * H5G_NODE_K(f)); indent += 3; fwidth = MAX(0, fwidth - 3); for (i = 0; i < sn->nsyms; i++) { - fprintf(stream, "%*sSymbol %d:\n", indent - 3, "", i); - if (H5F_addr_defined(heap) && - (s = H5H_peek(f, heap, sn->entry[i].name_off))) { - fprintf(stream, "%*s%-*s `%s'\n", indent, "", fwidth, - "Name:", - s); - } - H5G_ent_debug(f, sn->entry + i, stream, indent, fwidth); + fprintf(stream, "%*sSymbol %d:\n", indent - 3, "", i); + if (H5F_addr_defined(heap) && + (s = H5H_peek(f, heap, sn->entry[i].name_off))) { + fprintf(stream, "%*s%-*s `%s'\n", indent, "", fwidth, + "Name:", + s); + } + H5G_ent_debug(f, sn->entry + i, stream, indent, fwidth); } H5AC_unprotect(f, H5AC_SNODE, addr, sn); diff --git a/src/H5Gstab.c b/src/H5Gstab.c index 5b1ed90..7ef971c 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -65,9 +65,11 @@ H5G_stab_create(H5F_t *f, size_t init, H5G_entry_t *self /*out */ ) if (H5H_create(f, H5H_LOCAL, init, &(stab.heap_addr) /*out */ ) < 0) { HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap"); } - if ((name = H5H_insert(f, &(stab.heap_addr), 1, "") < 0)) { + name = H5H_insert(f, &(stab.heap_addr), 1, ""); + if ((size_t)(-1)==name) { HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap"); } + /* * B-tree's won't work if the first name isn't at the beginning * of the heap. @@ -529,7 +529,7 @@ H5H_remove_free(H5H_t *heap, H5H_free_t *fl) * * Return: Success: Offset of new item within heap. * - * Failure: FAIL + * Failure: (size_t)(-1) * * Programmer: Robb Matzke * matzke@llnl.gov @@ -551,18 +551,17 @@ H5H_insert(H5F_t *f, const haddr_t *addr, size_t buf_size, const void *buf) static nmessages = 0; #endif - FUNC_ENTER(H5H_insert, FAIL); + FUNC_ENTER(H5H_insert, (size_t)(-1)); /* check arguments */ assert(f); - if (!addr) - addr = &(f->shared->smallobj_addr); + if (!addr) addr = &(f->shared->smallobj_addr); assert(H5F_addr_defined(addr)); assert(buf_size > 0); assert(buf); if (NULL == (heap = H5AC_find(f, H5AC_HEAP, addr, NULL, NULL))) { - HRETURN_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, + HRETURN_ERROR(H5E_HEAP, H5E_CANTLOAD, (size_t)(-1), "unable to load heap"); } heap->dirty += 1; @@ -579,7 +578,8 @@ H5H_insert(H5F_t *f, const haddr_t *addr, size_t buf_size, const void *buf) * leave zero or at least H5G_SIZEOF_FREE bytes left over. */ for (fl = heap->freelist, found = FALSE; fl; fl = fl->next) { - if (fl->size > need_size && fl->size - need_size >= H5H_SIZEOF_FREE(f)) { + if (fl->size > need_size && + fl->size - need_size >= H5H_SIZEOF_FREE(f)) { /* a bigger free block was found */ offset = fl->offset; fl->offset += need_size; @@ -622,8 +622,8 @@ H5H_insert(H5F_t *f, const haddr_t *addr, size_t buf_size, const void *buf) fprintf(stderr, "H5H_insert: lost %lu bytes at line %d\n", (unsigned long) (max_fl->size), __LINE__); if (0 == nmessages++) { - fprintf(stderr, "Messages from H5H_insert() will go away " - "when assertions are turned off.\n"); + fprintf(stderr, "Messages from H5H_insert() will go " + "away when assertions are turned off.\n"); } } #endif @@ -102,7 +102,7 @@ H5P_term_interface(void) *------------------------------------------------------------------------- */ hid_t -H5Pcreate_simple(intn rank, size_t dims[]) +H5Pcreate_simple(int rank, size_t dims[]) { H5P_t *ds = NULL; hid_t ret_value = FAIL; @@ -301,7 +301,7 @@ H5P_close(H5P_t *ds) * *------------------------------------------------------------------------- */ -H5P_t * +H5P_t * H5P_copy(const H5P_t *src) { H5P_t *dst = NULL; @@ -421,8 +421,18 @@ H5P_get_npoints(const H5P_t *ds) break; case H5P_SIMPLE: - for (ret_value = 1, i = 0; i < ds->u.simple.rank; i++) { - ret_value *= ds->u.simple.size[i]; + /* + * Count the elements selected by the hypeslab if there is one, + * otherwise count all the elements. + */ + if (ds->hslab_def) { + for (ret_value=1, i=0; i<ds->u.simple.rank; i++) { + ret_value *= ds->h.count[i]; + } + } else { + for (ret_value=1, i=0; i<ds->u.simple.rank; i++) { + ret_value *= ds->u.simple.size[i]; + } } break; @@ -455,7 +465,7 @@ H5P_get_npoints(const H5P_t *ds) * *------------------------------------------------------------------------- */ -intn +int H5Pget_ndims(hid_t space_id) { H5P_t *ds = NULL; @@ -541,8 +551,8 @@ H5P_get_ndims(const H5P_t *ds) * *------------------------------------------------------------------------- */ -intn -H5Pget_dims(hid_t space_id, size_t dims[] /*out */ ) +int +H5Pget_dims(hid_t space_id, size_t dims[]/*out*/) { H5P_t *ds = NULL; @@ -684,7 +694,7 @@ H5P_modify(H5F_t *f, H5G_entry_t *ent, const H5P_t *ds) * *------------------------------------------------------------------------- */ -H5P_t * +H5P_t * H5P_read(H5F_t *f, H5G_entry_t *ent) { H5P_t *ds = NULL; @@ -895,7 +905,7 @@ H5Pis_simple(hid_t sid) be unlimited in size. --------------------------------------------------------------------------*/ herr_t -H5Pset_space(hid_t sid, intn rank, const size_t *dims) +H5Pset_space(hid_t sid, int rank, const size_t *dims) { H5P_t *space = NULL; /* dataspace to modify */ intn u; /* local counting variable */ @@ -1087,7 +1097,7 @@ done: * space. If no hyperslab has been defined then the hyperslab * is the same as the entire array. * - * Return: Success: SUCCEED + * Return: Success: Hyperslab dimensionality. * * Failure: FAIL * @@ -1098,11 +1108,12 @@ done: * *------------------------------------------------------------------------- */ -herr_t +int H5Pget_hyperslab (hid_t sid, size_t offset[]/*out*/, size_t size[]/*out*/, size_t stride[]/*out*/) { - H5P_t *ds = NULL; + const H5P_t *ds = NULL; + intn ret_value = FAIL; FUNC_ENTER (H5Pget_hyperslab, FAIL); H5ECLEAR; @@ -1113,12 +1124,12 @@ H5Pget_hyperslab (hid_t sid, size_t offset[]/*out*/, size_t size[]/*out*/, } /* Get hyperslab info */ - if (H5P_get_hyperslab (ds, offset, size, stride)<0) { + if ((ret_value=H5P_get_hyperslab (ds, offset, size, stride))<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to retrieve hyperslab information"); } - FUNC_LEAVE (SUCCEED); + FUNC_LEAVE (ret_value); } /*------------------------------------------------------------------------- @@ -1128,7 +1139,7 @@ H5Pget_hyperslab (hid_t sid, size_t offset[]/*out*/, size_t size[]/*out*/, * space. If no hyperslab has been defined then the hyperslab * is the same as the entire array. * - * Return: Success: SUCCEED + * Return: Success: Hyperslab dimensionality. * * Failure: FAIL * @@ -1139,11 +1150,12 @@ H5Pget_hyperslab (hid_t sid, size_t offset[]/*out*/, size_t size[]/*out*/, * *------------------------------------------------------------------------- */ -herr_t -H5P_get_hyperslab (H5P_t *ds, size_t offset[]/*out*/, size_t size[]/*out*/, - size_t stride[]/*out*/) +intn +H5P_get_hyperslab (const H5P_t *ds, size_t offset[]/*out*/, + size_t size[]/*out*/, size_t stride[]/*out*/) { intn i; + intn ret_value = FAIL; FUNC_ENTER (H5P_get_hyperslab, FAIL); @@ -1167,6 +1179,7 @@ H5P_get_hyperslab (H5P_t *ds, size_t offset[]/*out*/, size_t size[]/*out*/, if (stride) stride[i] = 1; } } + ret_value = ds->u.simple.rank; break; case H5P_COMPLEX: /*fall through*/ @@ -1175,7 +1188,7 @@ H5P_get_hyperslab (H5P_t *ds, size_t offset[]/*out*/, size_t size[]/*out*/, "hyperslabs not supported for this type of space"); } - FUNC_LEAVE (SUCCEED); + FUNC_LEAVE (ret_value); } diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 26e9673..63d2c6c 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -102,8 +102,8 @@ intn H5P_cmp (const H5P_t *ds1, const H5P_t *ds2); hbool_t H5P_is_simple (const H5P_t *sdim); uintn H5P_nelem (const H5P_t *space); const H5P_conv_t *H5P_find (const H5P_t *mem_space, const H5P_t *file_space); -herr_t H5P_get_hyperslab (H5P_t *ds, size_t offset[]/*out*/, - size_t size[]/*out*/, size_t stride[]/*out*/); +intn H5P_get_hyperslab (const H5P_t *ds, size_t offset[]/*out*/, + size_t size[]/*out*/, size_t stride[]/*out*/); /* Conversion functions for simple data spaces */ size_t H5P_simp_init (const struct H5O_layout_t *layout, diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index ddcfb04..7c4a850 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -39,17 +39,17 @@ extern "C" { #ifdef OLD_WAY hid_t H5Pcreate (H5P_class_t type); #endif /* OLD_WAY */ -hid_t H5Pcreate_simple (intn rank, size_t dims[]); +hid_t H5Pcreate_simple (int rank, size_t dims[]); herr_t H5Pclose (hid_t space_id); size_t H5Pget_npoints (hid_t space_id); -intn H5Pget_ndims (hid_t space_id); -intn H5Pget_dims (hid_t space_id, size_t dims[]); +int H5Pget_ndims (hid_t space_id); +int H5Pget_dims (hid_t space_id, size_t dims[]); hbool_t H5Pis_simple (hid_t space_id); -herr_t H5Pset_space (hid_t space_id, intn rank, const size_t *dims); +herr_t H5Pset_space (hid_t space_id, int rank, const size_t *dims); herr_t H5Pset_hyperslab(hid_t sid, const size_t *start, const size_t *count, const size_t *stride); -herr_t H5Pget_hyperslab (hid_t sid, size_t offset[]/*out*/, - size_t size[]/*out*/, size_t stride[]/*out*/); +int H5Pget_hyperslab (hid_t sid, size_t offset[]/*out*/, + size_t size[]/*out*/, size_t stride[]/*out*/); #ifdef __cplusplus } diff --git a/src/H5Psimp.c b/src/H5Psimp.c index 1cd46c4..89e576c 100644 --- a/src/H5Psimp.c +++ b/src/H5Psimp.c @@ -10,6 +10,7 @@ #include <H5private.h> #include <H5Eprivate.h> #include <H5Pprivate.h> +#include <H5Vprivate.h> /* Interface initialization */ #define PABLO_MASK H5P_simp_mask @@ -88,8 +89,11 @@ H5P_simp_fgath (H5F_t *f, const struct H5O_layout_t *layout, const H5P_number_t *numbering, intn start, intn nelmts, void *buf/*out*/) { - size_t offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */ - size_t size[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ + size_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ + size_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ + size_t zero[H5O_LAYOUT_NDIMS]; /*zero */ + size_t sample[H5O_LAYOUT_NDIMS]; /*hyperslab sampling */ + intn space_ndims; /*dimensionality of space*/ intn i; /*counters */ FUNC_ENTER (H5P_simp_fgath, 0); @@ -108,23 +112,34 @@ H5P_simp_fgath (H5F_t *f, const struct H5O_layout_t *layout, */ assert (0==start); assert (nelmts==H5P_get_npoints (file_space)); - + /* - * Quincey, this is where we look at FILE_SPACE to decide what the - * hyperslab is to read from disk. For now, since the H5P interface - * doesn't support hyperslabs, we'll assume the caller is asking for the - * entire array. --RPM + * Get hyperslab information to determine what elements are being + * selected (there might eventually be other selection methods too). + * We only support hyperslabs with unit sample because there's no way to + * currently pass sample information into H5F_arr_read() much less + * H5F_istore_read(). */ - assert (nelmts == H5P_get_npoints (file_space)); - for (i=0; i<layout->ndims; i++) offset[i] = 0; - i = H5P_get_dims (file_space, size); - assert (i+1 == layout->ndims); - size[i] = elmt_size; + if ((space_ndims=H5P_get_hyperslab (file_space, file_offset, hsize, + sample))<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0, + "unable to retrieve hyperslab parameters"); + } + for (i=0; i<space_ndims; i++) { + if (sample[i]!=1) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, 0, + "hyperslab sampling is not implemented yet"); + } + } + file_offset[space_ndims] = 0; + hsize[space_ndims] = elmt_size; + HDmemset (zero, 0, layout->ndims*sizeof(size_t)); /* * Gather from file. */ - if (H5F_arr_read (f, layout, size, size, offset, offset, buf/*out*/)<0) { + if (H5F_arr_read (f, layout, hsize, hsize, zero, file_offset, + buf/*out*/)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); } @@ -157,6 +172,14 @@ H5P_simp_mscat (const void *tconv_buf, size_t elmt_size, const H5P_t *mem_space, const H5P_number_t *numbering, intn start, intn nelmts, void *buf/*out*/) { + size_t mem_offset[H5O_LAYOUT_NDIMS]; /*slab offset in app buf*/ + size_t mem_size[H5O_LAYOUT_NDIMS]; /*total size of app buf */ + size_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ + size_t zero[H5O_LAYOUT_NDIMS]; /*zero */ + size_t sample[H5O_LAYOUT_NDIMS]; /*hyperslab sampling */ + intn space_ndims; /*dimensionality of space*/ + intn i; /*counters */ + FUNC_ENTER (H5P_simp_mscat, FAIL); /* Check args */ @@ -174,12 +197,39 @@ H5P_simp_mscat (const void *tconv_buf, size_t elmt_size, assert (nelmts==H5P_get_npoints (mem_space)); /* - * Quincey, this is where we look at the hyperslab spec of MEM_SPACE to - * figure out how to scatter. You'll probably end up calling - * H5V_hyper_copy(), but for now we just assume that data points - * are copied directly from TCONV_BUF to BUF. + * Retrieve hyperslab information to determine what elements are being + * selected (there might be other selection methods in the future). We + * only handle hyperslabs with unit sample because there's currently no + * way to pass sample information to H5V_hyper_copy(). + */ + if ((space_ndims=H5P_get_hyperslab (mem_space, mem_offset, hsize, + sample))<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, + "unable to retrieve hyperslab parameters"); + } + for (i=0; i<space_ndims; i++) { + if (sample[i]!=1) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "hyperslab sampling is not implemented yet"); + } + } + if (H5P_get_dims (mem_space, mem_size)<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, + "unable to retrieve data space dimensions"); + } + mem_offset[space_ndims] = 0; + mem_size[space_ndims] = elmt_size; + hsize[space_ndims] = elmt_size; + HDmemset (zero, 0, (space_ndims+1)*sizeof(size_t)); + + /* + * Scatter from conversion buffer to application memory. */ - HDmemcpy (buf, tconv_buf, nelmts*elmt_size); + if (H5V_hyper_copy (space_ndims+1, hsize, mem_size, mem_offset, buf, + hsize, zero, tconv_buf)<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, + "unable to scatter data to memory"); + } FUNC_LEAVE (SUCCEED); } @@ -212,6 +262,14 @@ H5P_simp_mgath (const void *buf, size_t elmt_size, const H5P_t *mem_space, const H5P_number_t *numbering, intn start, intn nelmts, void *tconv_buf/*out*/) { + size_t mem_offset[H5O_LAYOUT_NDIMS]; /*slab offset in app buf*/ + size_t mem_size[H5O_LAYOUT_NDIMS]; /*total size of app buf */ + size_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ + size_t zero[H5O_LAYOUT_NDIMS]; /*zero */ + size_t sample[H5O_LAYOUT_NDIMS]; /*hyperslab sampling */ + intn space_ndims; /*dimensionality of space*/ + intn i; /*counters */ + FUNC_ENTER (H5P_simp_mgath, 0); /* Check args */ @@ -229,12 +287,39 @@ H5P_simp_mgath (const void *buf, size_t elmt_size, assert (nelmts==H5P_get_npoints (mem_space)); /* - * Quincey, this is where we look at the hyperslab spec of MEM_SPACE to - * figure out how to gather. You'll probably end up calling - * H5V_hyper_copy(), but for now we just assume that data points are - * copied directly from BUF to TCONV_BUF. + * Retrieve hyperslab information to determine what elements are being + * selected (there might be other selection methods in the future). We + * only handle hyperslabs with unit sample because there's currently no + * way to pass sample information to H5V_hyper_copy(). + */ + if ((space_ndims=H5P_get_hyperslab (mem_space, mem_offset, hsize, + sample))<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0, + "unable to retrieve hyperslab parameters"); + } + for (i=0; i<space_ndims; i++) { + if (sample[i]!=1) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, 0, + "hyperslab sampling is not implemented yet"); + } + } + if (H5P_get_dims (mem_space, mem_size)<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0, + "unable to retrieve data space dimensions"); + } + mem_offset[space_ndims] = 0; + mem_size[space_ndims] = elmt_size; + hsize[space_ndims] = elmt_size; + HDmemset (zero, 0, (space_ndims+1)*sizeof(size_t)); + + /* + * Scatter from conversion buffer to application memory. */ - HDmemcpy (tconv_buf, buf, nelmts*elmt_size); + if (H5V_hyper_copy (space_ndims+1, hsize, hsize, zero, tconv_buf, + mem_size, mem_offset, buf)<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0, + "unable to scatter data to memory"); + } FUNC_LEAVE (nelmts); } @@ -267,8 +352,11 @@ H5P_simp_fscat (H5F_t *f, const struct H5O_layout_t *layout, const H5P_number_t *numbering, intn start, intn nelmts, const void *buf) { - size_t offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */ - size_t size[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ + size_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */ + size_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ + size_t zero[H5O_LAYOUT_NDIMS]; /*zero vector */ + size_t sample[H5O_LAYOUT_NDIMS]; /*hyperslab sampling */ + intn space_ndims; /*space dimensionality */ intn i; /*counters */ FUNC_ENTER (H5P_simp_fscat, FAIL); @@ -289,22 +377,32 @@ H5P_simp_fscat (H5F_t *f, const struct H5O_layout_t *layout, assert (nelmts==H5P_get_npoints (file_space)); /* - * Quincey, this is where we look at FILE_SPACE to decide what the - * hyperslab is to read from disk. For now, since the H5P interface - * doesn't support hyperslabs, we'll assume the caller is asking for the - * entire array. --RPM + * Get hyperslab information to determine what elements are being + * selected (there might eventually be other selection methods too). + * We only support hyperslabs with unit sample because there's no way to + * currently pass sample information into H5F_arr_read() much less + * H5F_istore_read(). */ - assert (nelmts == H5P_get_npoints (file_space)); - for (i=0; i<layout->ndims; i++) offset[i] = 0; - i = H5P_get_dims (file_space, size); - assert (i+1 == layout->ndims); - size[i] = elmt_size; + if ((space_ndims=H5P_get_hyperslab (file_space, file_offset, hsize, + sample))<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, + "unable to retrieve hyperslab parameters"); + } + for (i=0; i<space_ndims; i++) { + if (sample[i]!=1) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "hyperslab sampling is not implemented yet"); + } + } + file_offset[space_ndims] = 0; + hsize[space_ndims] = elmt_size; + HDmemset (zero, 0, layout->ndims*sizeof(size_t)); /* * Scatter to file. */ - if (H5F_arr_write (f, layout, size, size, offset, offset, buf/*out*/)<0) { - HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); + if (H5F_arr_write (f, layout, hsize, hsize, zero, file_offset, buf)<0) { + HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); } FUNC_LEAVE (SUCCEED); diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index e45c8ea..1836a79 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -95,11 +95,24 @@ main (void) static s5_t s5[NX*NY]; hid_t s5_tid; + /* Sixth dataset */ + + /* Seventh dataset */ + hid_t s7_sid; + + /* Eighth dataset */ + s1_t *s8 = NULL; + hid_t s8_f_sid; /*file data space */ + hid_t s8_m_sid; /*memory data space */ + /* Other variables */ int i; hid_t file, dataset, space; herr_t status; static size_t dim[] = {NX, NY}; + size_t f_offset[2]; /*offset of hyperslab in file */ + size_t h_size[2]; /*size of hyperslab */ + size_t h_sample[2]; /*hyperslab sampling */ /* Create the file */ file = H5Fcreate ("cmpd_dset.h5", H5ACC_OVERWRITE, @@ -123,9 +136,9 @@ STEP 1: Initialize dataset `s1' and store it on disk in native order.\n"); /* Initialize the dataset */ for (i=0; i<NX*NY; i++) { s1[i].a = 5*i+0; - s1[i].b = 5*i+1; + s1[i].b = 2000*2*i; s1[i].c = 5*i+2; - s1[i].d = 5*i+3; + s1[i].d = 2001+2*i; s1[i].e = 5*i+4; } @@ -297,8 +310,8 @@ STEP 6: Update fields `b' and `d' on the file, leaving the other fields\n\ /* Initialize `s4' with new values */ for (i=0; i<NX*NY; i++) { - s4[i].b = 2000+2*i; - s4[i].d = 2001+2*i; + s4[i].b = 5*i+1; + s4[i].d = 5*i+3; } /* Write the data to file */ @@ -306,23 +319,75 @@ STEP 6: Update fields `b' and `d' on the file, leaving the other fields\n\ assert (status>=0); /* Read the data back */ - status = H5Dread (dataset, s2_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s2); + status = H5Dread (dataset, s1_tid, H5P_ALL, H5P_ALL, H5C_DEFAULT, s1); + assert (status>=0); + + /* Compare */ + for (i=0; i<NX*NY; i++) { + assert (s1[i].a == 5*i+0); + assert (s1[i].b == 5*i+1); + assert (s1[i].c == 5*i+2); + assert (s1[i].d == 5*i+3); + assert (s1[i].e == 5*i+4); + } + + /* + *###################################################################### + * STEP 7. Read the original dataset with an explicit data space. Even + * though these data spaces are equal it tests a different part of the + * library. + */ + printf ("\ +STEP 7: Reading original dataset with explicit data space.\n"); + fflush (stdout); + + /* Create the data space */ + s7_sid = H5Pcreate_simple (2, dim); + assert (s7_sid>=0); + + /* Read the dataset */ + status = H5Dread (dataset, s2_tid, s7_sid, H5P_ALL, H5C_DEFAULT, s2); assert (status>=0); /* Compare */ for (i=0; i<NX*NY; i++) { assert (s2[i].a == s1[i].a); - assert (s2[i].b == s4[i].b); + assert (s2[i].b == s1[i].b); assert (s2[i].c == s1[i].c); - assert (s2[i].d == s4[i].d); + assert (s2[i].d == s1[i].d); assert (s2[i].e == s1[i].e); } + /* + *###################################################################### + * STEP 8. Read a hyperslab of the file into a complete array in memory. + * The hyperslab is the middle third of the array. + */ + printf ("\ +STEP 8: Read middle third hyperslab into memory array.\n"); + fflush (stdout); + /* Create the file data space */ + s8_f_sid = H5Dget_space (dataset); + assert (s8_f_sid>=0); + f_offset[0] = NX/3; + f_offset[1] = NY/3; + h_size[0] = 2*NX/3 - f_offset[0]; + h_size[1] = 2*NY/3 - f_offset[0]; + h_sample[0] = 1; + h_sample[1] = 1; + status = H5Pset_hyperslab (s8_f_sid, f_offset, h_size, h_sample); + assert (status>=0); + /* Create memory data space */ + s8_m_sid = H5Pcreate_simple (2, h_size); + assert (s8_m_sid>=0); - + /* Read the dataset */ + s8 = calloc (h_size[0]*h_size[1], sizeof(s1_t)); + status = H5Dread (dataset, s1_tid, s8_m_sid, s8_f_sid, H5C_DEFAULT, s8); + assert (status>=0); /* diff --git a/test/testhdf5.h b/test/testhdf5.h index d13f08a..ed9e0a3 100644 --- a/test/testhdf5.h +++ b/test/testhdf5.h @@ -33,7 +33,7 @@ extern int Verbosity; /* Used to make certain a return value _is_not_ a value */ #define CHECK(ret, val, where) \ do {if (Verbosity>9) print_func(" Call to routine: %15s at line %4d in %s returned %ld \n",where,(int)__LINE__,__FILE__,(long)ret);\ -if(ret == val) {print_func("*** UNEXPECTED RETURN from %s is %ld at line %4d in %s\n", where, (long)ret, (int)__LINE__,__FILE__); num_errs++;H5Eprint (H5E_thrdid_g, stdout);} \ +if(ret == val) {print_func("*** UNEXPECTED RETURN from %s is %ld at line %4d in %s\n", where, (long)ret, (int)__LINE__,__FILE__); num_errs++;H5Eprint (H5E_thrdid_g, stdout);} H5Eclear(H5E_thrdid_g);\ } while(0) #define CHECK_I(ret,where) { \ @@ -47,6 +47,7 @@ if(ret == val) {print_func("*** UNEXPECTED RETURN from %s is %ld at line %4d in H5Eprint (H5E_thrdid_g, stdout); \ num_errs++; \ } \ + H5Eclear (H5E_thrdid_g); \ } #define CHECK_PTR(ret,where) { \ @@ -60,12 +61,13 @@ if(ret == val) {print_func("*** UNEXPECTED RETURN from %s is %ld at line %4d in H5Eprint (H5E_thrdid_g, stdout); \ num_errs++; \ } \ + H5Eclear (H5E_thrdid_g); \ } /* Used to make certain a return value _is_ a value */ #define VERIFY(x, val, where) \ do {if (Verbosity>9) print_func(" Call to routine: %15s at line %4d in %s had value %ld \n",where,(int)__LINE__,__FILE__,(long)x);\ -if(x != val) {print_func("*** UNEXPECTED VALUE from %s is %ld at line %4d in %s\n", where, (long)x,(int)__LINE__,__FILE__); H5Eprint (H5E_thrdid_g, stdout); num_errs++;} \ +if(x != val) {print_func("*** UNEXPECTED VALUE from %s is %ld at line %4d in %s\n", where, (long)x,(int)__LINE__,__FILE__); H5Eprint (H5E_thrdid_g, stdout);num_errs++;}H5Eclear(H5E_thrdid_g); \ } while(0) /* Used to document process through a test and to check for errors */ @@ -73,7 +75,7 @@ if(x != val) {print_func("*** UNEXPECTED VALUE from %s is %ld at line %4d in %s\ do { \ if (Verbosity>8) print_func(" Call to routine: %15s at line %4d in %s returned %ld \n",func,(int)__LINE__,__FILE__,(long)ret); \ if (Verbosity>9) HEprint(stdout,0); \ -if(ret == FAIL) {print_func("*** UNEXPECTED RETURN from %s is %ld at line %4d in %s\n", func, (long)ret,(int)__LINE__,__FILE__); H5Eprint (H5E_thrdid_g, stdout); num_errs++;} \ +if(ret == FAIL) {print_func("*** UNEXPECTED RETURN from %s is %ld at line %4d in %s\n", func, (long)ret,(int)__LINE__,__FILE__); H5Eprint (H5E_thrdid_g, stdout); num_errs++;} H5Eclear(H5E_thrdid_g);\ } while(0) /* Used to document process through a test */ |