From be7efff2b77fad3710f1d9b1e801d7a89d4134d5 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Tue, 6 Apr 2004 15:08:20 -0500 Subject: [svn-r8314] Purpose: Progressive check-in Description: NULL dataspace. This step is mainly for dataspace header message and a test. Solution: The test mainly checks NULL dataspace features. Backward compatibility is tested in the fill value test. Platforms tested: h5committest --- src/H5D.c | 6 +- src/H5O.c | 4 +- src/H5Ofill.c | 2 +- src/H5Opkg.h | 7 +- src/H5Oprivate.h | 3 +- src/H5Osdspace.c | 439 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/H5S.c | 144 ++++++++++++++---- src/H5Sall.c | 5 + src/H5Snone.c | 4 +- src/H5Spkg.h | 3 +- 10 files changed, 574 insertions(+), 43 deletions(-) diff --git a/src/H5D.c b/src/H5D.c index fa20fd4..f77911a 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -1905,8 +1905,10 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy dataspace") /* Set the dataset's dataspace to 'all' selection */ - if(H5S_select_all(new_dset->space,1)<0) - HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection") + if(H5S_NULL != H5S_get_simple_extent_type(new_dset->space)) { + if(H5S_select_all(new_dset->space,1)<0) + HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection") + } /* Check if the dataset has a non-default DCPL & get important values, if so */ if(new_dset->dcpl_id!=H5P_DATASET_CREATE_DEFAULT) { diff --git a/src/H5O.c b/src/H5O.c index c2ff4f8..63b0719 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -104,8 +104,8 @@ static herr_t H5O_init_interface(void); /* ID to type mapping */ static const H5O_class_t *const message_type_g[] = { H5O_NULL, /*0x0000 Null */ - H5O_SDSPACE, /*0x0001 Simple Dimensionality */ - NULL, /*0x0002 Data space (fiber bundle?) */ + H5O_SDSPACE, /*0x0001 Simple Dimensionality (old) */ + H5O_SDSPACE_NEW, /*0x0002 Extent Dimensionality (new) */ H5O_DTYPE, /*0x0003 Data Type */ H5O_FILL, /*0x0004 Old data storage -- fill value */ H5O_FILL_NEW, /*0x0005 New Data storage -- fill value */ diff --git a/src/H5Ofill.c b/src/H5Ofill.c index 521b94d..1870f85 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -85,7 +85,7 @@ const H5O_class_t H5O_FILL_NEW[1] = {{ H5O_fill_new_debug, /*debug the message */ }}; -/* Initial version of the "new" fill value information */ +/* Initial version of the "old" fill value information */ #define H5O_FILL_VERSION 1 /* Revised version of the "new" fill value information */ #define H5O_FILL_VERSION_2 2 diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 866e1b7..a92543e 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -109,11 +109,16 @@ typedef struct H5O_t { H5_DLLVAR const H5O_class_t H5O_NULL[1]; /* - * Simple Data Space Message. + * Old simple Data Space Message. */ H5_DLLVAR const H5O_class_t H5O_SDSPACE[1]; /* + * New Extent Data Space Message. + */ +H5_DLLVAR const H5O_class_t H5O_SDSPACE_NEW[1]; + +/* * Data Type Message. */ H5_DLLVAR const H5O_class_t H5O_DTYPE[1]; diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 49cb08e..330d949 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -52,7 +52,8 @@ /* Header message IDs */ #define H5O_NULL_ID 0x0000 /* Null Message. */ -#define H5O_SDSPACE_ID 0x0001 /* Simple Dataspace Message. */ +#define H5O_SDSPACE_ID 0x0001 /* Simple Dataspace Message.(old) */ +#define H5O_SDSPACE_NEW_ID 0x0002 /* Simple Dataspace Message.(new) */ /* Complex dataspace is/was planned for message 0x0002 */ #define H5O_DTYPE_ID 0x0003 /* Datatype Message. */ #define H5O_FILL_ID 0x0004 /* Fill Value Message. (Old) */ diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index cc24e19..e293d94 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -25,7 +25,17 @@ #define PABLO_MASK H5O_sdspace_mask -/* PRIVATE PROTOTYPES */ +/* new PRIVATE PROTOTYPES */ +static void *H5O_sdspace_new_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh); +static herr_t H5O_sdspace_new_encode(H5F_t *f, uint8_t *p, const void *_mesg); +static void *H5O_sdspace_new_copy(const void *_mesg, void *_dest); +static size_t H5O_sdspace_new_size(H5F_t *f, const void *_mesg); +static herr_t H5O_sdspace_new_reset(void *_mesg); +static herr_t H5O_sdspace_new_free (void *_mesg); +static herr_t H5O_sdspace_new_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, + FILE * stream, int indent, int fwidth); + +/* old PRIVATE PROTOTYPES */ static void *H5O_sdspace_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh); static herr_t H5O_sdspace_encode(H5F_t *f, uint8_t *p, const void *_mesg); static void *H5O_sdspace_copy(const void *_mesg, void *_dest); @@ -35,7 +45,7 @@ static herr_t H5O_sdspace_free (void *_mesg); static herr_t H5O_sdspace_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int indent, int fwidth); -/* This message derives from H5O */ +/* This message derives from H5O, for old dataspace before version 1.7 */ const H5O_class_t H5O_SDSPACE[1] = {{ H5O_SDSPACE_ID, /* message id number */ "simple_dspace", /* message name for debugging */ @@ -53,7 +63,28 @@ const H5O_class_t H5O_SDSPACE[1] = {{ H5O_sdspace_debug, /* debug the message */ }}; +/* This message derives from H5O, for new dataspace after version 1.6 */ +const H5O_class_t H5O_SDSPACE_NEW[1] = {{ + H5O_SDSPACE_NEW_ID, /* message id number */ + "extent_dataspace", /* message name for debugging */ + sizeof(H5S_extent_t), /* native message size */ + H5O_sdspace_new_decode, /* decode message */ + H5O_sdspace_new_encode, /* encode message */ + H5O_sdspace_new_copy, /* copy the native value */ + H5O_sdspace_new_size, /* size of symbol table entry */ + H5O_sdspace_new_reset, /* default reset method */ + H5O_sdspace_new_free, /* free method */ + NULL, /* file delete method */ + NULL, /* link method */ + NULL, /* get share method */ + NULL, /* set share method */ + H5O_sdspace_new_debug, /* debug the message */ +}}; + +/* Initial version of the "old" data space information */ #define H5O_SDSPACE_VERSION 1 +/* Initial version of the "new" data space information */ +#define H5O_SDSPACE_VERSION_2 2 /* Is the interface initialized? */ static int interface_initialize_g = 0; @@ -62,12 +93,103 @@ static int interface_initialize_g = 0; /* Declare external the free list for H5S_simple_t's */ H5FL_EXTERN(H5S_simple_t); +/* Declare external the free list for H5S_extent_t's */ +H5FL_EXTERN(H5S_extent_t); + /* Declare external the free list for hsize_t arrays */ H5FL_ARR_EXTERN(hsize_t); /*-------------------------------------------------------------------------- NAME + H5O_sdspace_new_decode + PURPOSE + Decode a extent dimensionality message and return a pointer to a memory + struct with the decoded information + USAGE + void *H5O_sdspace_decode(f, raw_size, p) + H5F_t *f; IN: pointer to the HDF5 file struct + size_t raw_size; IN: size of the raw information buffer + const uint8 *p; IN: the raw information buffer + RETURNS + Pointer to the new message in native order on success, NULL on failure + DESCRIPTION + This function decodes the "raw" disk form of an extent dimensionality + message into a struct in memory native format. The struct is allocated + within this function using malloc() and is returned to the caller. + + MODIFICATIONS +--------------------------------------------------------------------------*/ +static void * +H5O_sdspace_new_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *sh) +{ + H5S_extent_t *sdim = NULL;/* New extent dimensionality structure */ + void *ret_value; + unsigned i; /* local counting variable */ + unsigned flags, version; + + FUNC_ENTER_NOAPI(H5O_sdspace_new_decode, NULL); + + /* check args */ + assert(f); + assert(p); + assert (!sh); + + /* decode */ + if ((sdim = H5FL_CALLOC(H5S_extent_t)) != NULL) { + version = *p++; + if (version!=H5O_SDSPACE_VERSION && version!=H5O_SDSPACE_VERSION_2) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "wrong version number in data space message"); + if(version==H5O_SDSPACE_VERSION_2) + sdim->type = *p++; + sdim->u.simple.rank = *p++; + if (sdim->u.simple.rank>H5S_MAX_RANK) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "simple data space dimensionality is too large"); + flags = *p++; + + if(version==H5O_SDSPACE_VERSION) { + p += 5; /*reserved*/ + } else if(version==H5O_SDSPACE_VERSION_2) { + p += 4; /*reserved*/ + } + + if (sdim->u.simple.rank > 0) { + if (NULL==(sdim->u.simple.size=H5FL_ARR_MALLOC(hsize_t,sdim->u.simple.rank))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + for (i = 0; i < sdim->u.simple.rank; i++) + H5F_DECODE_LENGTH (f, p, sdim->u.simple.size[i]); + if (flags & H5S_VALID_MAX) { + if (NULL==(sdim->u.simple.max=H5FL_ARR_MALLOC(hsize_t,sdim->u.simple.rank))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + for (i = 0; i < sdim->u.simple.rank; i++) + H5F_DECODE_LENGTH (f, p, sdim->u.simple.max[i]); + } +#ifdef LATER + if (flags & H5S_VALID_PERM) { + if (NULL==(sdim->u.simple.perm=H5FL_ARR_MALLOC(hsize_t,sdim->u.simple.rank))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + for (i = 0; i < sdim->u.simple.rank; i++) + H5F_DECODE_LENGTH (f, p, sdim->u.simple.perm[i]); + } +#endif /* LATER */ + } + } + + /* Set return value */ + ret_value = (void*)sdim; /*success*/ + +done: + if (!ret_value && sdim) { + H5S_release_extent(sdim); + H5FL_FREE(H5S_extent_t,sdim); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*-------------------------------------------------------------------------- + NAME H5O_sdspace_decode PURPOSE Decode a simple dimensionality message and return a pointer to a memory @@ -155,6 +277,79 @@ done: /*-------------------------------------------------------------------------- NAME + H5O_sdspace_new_encode + PURPOSE + Encode a simple dimensionality message + USAGE + herr_t H5O_sdspace_encode(f, raw_size, p, mesg) + H5F_t *f; IN: pointer to the HDF5 file struct + size_t raw_size; IN: size of the raw information buffer + const uint8 *p; IN: the raw information buffer + const void *mesg; IN: Pointer to the extent dimensionality struct + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + This function encodes the native memory form of the simple + dimensionality message in the "raw" disk form. + + MODIFICATIONS + +--------------------------------------------------------------------------*/ +static herr_t +H5O_sdspace_new_encode(H5F_t *f, uint8_t *p, const void *mesg) +{ + const H5S_extent_t *sdim = (const H5S_extent_t *) mesg; + unsigned u; /* Local counting variable */ + unsigned flags = 0; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_sdspace_new_encode, FAIL); + + /* check args */ + assert(f); + assert(p); + assert(sdim); + + /* set flags */ + if (sdim->u.simple.max) + flags |= H5S_VALID_MAX; +#ifdef LATER + if (sdim->u.simple.perm) + flags |= H5S_VALID_PERM; +#endif + + /* encode */ + *p++ = H5O_SDSPACE_VERSION_2; + *p++ = sdim->type; + *p++ = sdim->u.simple.rank; + *p++ = flags; + *p++ = 0; /*reserved*/ + *p++ = 0; /*reserved*/ + *p++ = 0; /*reserved*/ + *p++ = 0; /*reserved*/ + + if (sdim->u.simple.rank > 0) { + for (u = 0; u < sdim->u.simple.rank; u++) + H5F_ENCODE_LENGTH (f, p, sdim->u.simple.size[u]); + if (flags & H5S_VALID_MAX) { + for (u = 0; u < sdim->u.simple.rank; u++) + H5F_ENCODE_LENGTH (f, p, sdim->u.simple.max[u]); + } +#ifdef LATER + if (flags & H5S_VALID_PERM) { + for (u = 0; u < sdim->u.simple.rank; u++) + H5F_ENCODE_LENGTH (f, p, sdim->u.simple.perm[u]); + } +#endif + } + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*-------------------------------------------------------------------------- + NAME H5O_sdspace_encode PURPOSE Encode a simple dimensionality message @@ -233,6 +428,64 @@ done: /*-------------------------------------------------------------------------- NAME + H5O_sdspace_new_copy + PURPOSE + Copies a message from MESG to DEST, allocating DEST if necessary. + USAGE + void *H5O_sdspace_copy(mesg, dest) + const void *mesg; IN: Pointer to the source extent dimensionality struct + const void *dest; IN: Pointer to the destination extent dimensionality struct + RETURNS + Pointer to DEST on success, NULL on failure + DESCRIPTION + This function copies a native (memory) extent dimensionality message, + allocating the destination structure if necessary. +--------------------------------------------------------------------------*/ +static void * +H5O_sdspace_new_copy(const void *mesg, void *dest) +{ + const H5S_extent_t *src = (const H5S_extent_t *) mesg; + H5S_extent_t *dst = (H5S_extent_t *) dest; + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_sdspace_new_copy, NULL); + + /* check args */ + assert(src); + if (!dst && NULL==(dst = H5FL_MALLOC(H5S_extent_t))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* deep copy -- pointed-to values are copied also */ + HDmemcpy(dst, src, sizeof(H5S_extent_t)); + + if (src->u.simple.size) { + if (NULL==(dst->u.simple.size = H5FL_ARR_MALLOC(hsize_t,src->u.simple.rank))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HDmemcpy (dst->u.simple.size, src->u.simple.size, src->u.simple.rank*sizeof(src->u.simple.size[0])); + } + if (src->u.simple.max) { + if (NULL==(dst->u.simple.max=H5FL_ARR_MALLOC(hsize_t,src->u.simple.rank))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HDmemcpy (dst->u.simple.max, src->u.simple.max, src->u.simple.rank*sizeof(src->u.simple.max[0])); + } +#ifdef LATER + if (src->u.simple.perm) { + if (NULL==(dst->u.simple.perm=H5FL_ARR_MALLOC(hsize_t,src->u.simple.rank))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HDmemcpy (dst->u.simple.perm, src->u.simple.perm, src->u.simple.rank*sizeof(src->u.simple.perm[0])); + } +#endif + + /* Set return value */ + ret_value=dst; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*-------------------------------------------------------------------------- + NAME H5O_sdspace_copy PURPOSE Copies a message from MESG to DEST, allocating DEST if necessary. @@ -291,6 +544,52 @@ done: /*-------------------------------------------------------------------------- NAME + H5O_sdspace_new_size + PURPOSE + Return the raw message size in bytes + USAGE + void *H5O_sdspace_new_size(f, mesg) + H5F_t *f; IN: pointer to the HDF5 file struct + const void *mesg; IN: Pointer to the source extent dimensionality struct + RETURNS + Size of message on success, zero on failure + DESCRIPTION + This function returns the size of the raw extent dimensionality message on + success. (Not counting the message type or size fields, only the data + portion of the message). It doesn't take into account alignment. + + MODIFICATIONS +--------------------------------------------------------------------------*/ +static size_t +H5O_sdspace_new_size(H5F_t *f, const void *mesg) +{ + const H5S_extent_t *space = (const H5S_extent_t *) mesg; + + /* + * All dimensionality messages are at least 8 bytes long. + */ + size_t ret_value = 8; + + FUNC_ENTER_NOAPI(H5O_sdspace_new_size, 0); + + /* add in the dimension sizes */ + ret_value += space->u.simple.rank * H5F_SIZEOF_SIZE (f); + + /* add in the space for the maximum dimensions, if they are present */ + ret_value += space->u.simple.max ? space->u.simple.rank * H5F_SIZEOF_SIZE (f) : 0; + +#ifdef LATER + /* add in the space for the dimension permutations, if they are present */ + ret_value += space->u.simple.perm ? space->u.simple.rank * 4 : 0; +#endif + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*-------------------------------------------------------------------------- + NAME H5O_sdspace_size PURPOSE Return the raw message size in bytes @@ -339,6 +638,36 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_sdspace_new_reset + * + * Purpose: Frees the inside of a dataspace message and resets it to some + * initial value. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Wednesday, March 31, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_sdspace_new_reset(void *_mesg) +{ + H5S_extent_t *mesg = (H5S_extent_t*)_mesg; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_sdspace_new_reset, FAIL); + + H5S_release_extent(mesg); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- * Function: H5O_sdspace_reset * * Purpose: Frees the inside of a dataspace message and resets it to some @@ -369,6 +698,36 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_sdsdpace_new_free + * + * Purpose: Free's the message + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Wednesday, March 31, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_sdspace_new_free (void *mesg) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_sdspace_new_free, FAIL); + + assert (mesg); + + H5FL_FREE(H5S_extent_t,mesg); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*------------------------------------------------------------------------- * Function: H5O_sdsdpace_free * * Purpose: Free's the message @@ -400,6 +759,82 @@ done: /*-------------------------------------------------------------------------- NAME + H5O_sdspace_new_debug + PURPOSE + Prints debugging information for an extent dimensionality message + USAGE + void *H5O_sdspace_new_debug(f, mesg, stream, indent, fwidth) + H5F_t *f; IN: pointer to the HDF5 file struct + const void *mesg; IN: Pointer to the source extent dimensionality struct + FILE *stream; IN: Pointer to the stream for output data + int indent; IN: Amount to indent information by + int fwidth; IN: Field width (?) + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + This function prints debugging output to the stream passed as a + parameter. +--------------------------------------------------------------------------*/ +static herr_t +H5O_sdspace_new_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *mesg, + FILE * stream, int indent, int fwidth) +{ + const H5S_extent_t *sdim = (const H5S_extent_t *) mesg; + unsigned u; /* local counting variable */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_sdspace_new_debug, FAIL); + + /* check args */ + assert(f); + assert(sdim); + assert(stream); + assert(indent >= 0); + assert(fwidth >= 0); + + HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, + "Rank:", + (unsigned long) (sdim->u.simple.rank)); + + if(sdim->u.simple.rank>0) { + HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Dim Size:"); + for (u = 0; u < sdim->u.simple.rank; u++) + HDfprintf (stream, "%s%Hu", u?", ":"", sdim->u.simple.size[u]); + HDfprintf (stream, "}\n"); + + HDfprintf(stream, "%*s%-*s ", indent, "", fwidth, "Dim Max:"); + if (sdim->u.simple.max) { + HDfprintf (stream, "{"); + for (u = 0; u < sdim->u.simple.rank; u++) { + if (H5S_UNLIMITED==sdim->u.simple.max[u]) { + HDfprintf (stream, "%sINF", u?", ":""); + } else { + HDfprintf (stream, "%s%Hu", u?", ":"", sdim->u.simple.max[u]); + } + } + HDfprintf (stream, "}\n"); + } else { + HDfprintf (stream, "CONSTANT\n"); + } + +#ifdef LATER + if (sdim->u.simple.perm) { + HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Dim Perm:"); + for (u = 0; u < sdim->u.simple.rank; u++) { + HDfprintf (stream, "%s%lu", u?", ":"", + (unsigned long) (sdim->u.simple.perm[u])); + } + } +#endif + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + + +/*-------------------------------------------------------------------------- + NAME H5O_sdspace_debug PURPOSE Prints debugging information for a simple dimensionality message diff --git a/src/H5S.c b/src/H5S.c index eef5d7e..d2feb43 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -56,6 +56,9 @@ hbool_t H5S_mpi_opt_types_g = TRUE; /* Declare a free list to manage the H5S_simple_t struct */ H5FL_DEFINE(H5S_simple_t); +/* Declare a free list to manage the H5S_extent_t struct */ +H5FL_DEFINE(H5S_extent_t); + /* Declare a free list to manage the H5S_t struct */ H5FL_DEFINE(H5S_t); @@ -541,6 +544,45 @@ H5S_release_simple(H5S_simple_t *simple) done: FUNC_LEAVE_NOAPI(ret_value); } + + +/*------------------------------------------------------------------------- + * Function: H5S_release_extent + * + * Purpose: Releases all memory associated with an extent data space. + * (but doesn't free the extent space itself) + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Wednesday, March 31, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5S_release_extent(H5S_extent_t *extent) +{ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5S_release_extent, FAIL); + + assert(extent); + + if(extent->u.simple.size) + H5FL_ARR_FREE(hsize_t,extent->u.simple.size); + if(extent->u.simple.max) + H5FL_ARR_FREE(hsize_t,extent->u.simple.max); +#ifdef LATER + if(extent->u.simple.perm) + H5FL_ARR_FREE(hsize_t,extent->u.simple.perm); +#endif /* LATER */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} + /*------------------------------------------------------------------------- * Function: H5Scopy @@ -1096,7 +1138,7 @@ H5S_modify(H5G_entry_t *ent, const H5S_t *ds, hbool_t update_time, hid_t dxpl_id case H5S_NULL: case H5S_SCALAR: case H5S_SIMPLE: - if (H5O_modify(ent, H5O_SDSPACE_ID, 0, 0, update_time, &(ds->extent.u.simple), dxpl_id)<0) + if (H5O_modify(ent, H5O_SDSPACE_NEW_ID, 0, 0, update_time, &(ds->extent), dxpl_id)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple data space message"); break; @@ -1143,7 +1185,7 @@ H5S_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, const H5S_t *ds) case H5S_NULL: case H5S_SCALAR: case H5S_SIMPLE: - if (H5O_append(f, dxpl_id, oh, H5O_SDSPACE_ID, 0, &(ds->extent.u.simple))<0) + if (H5O_append(f, dxpl_id, oh, H5O_SDSPACE_NEW_ID, 0, &(ds->extent))<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple data space message"); break; @@ -1192,38 +1234,76 @@ H5S_read(H5G_entry_t *ent, hid_t dxpl_id) if (NULL==(ds = H5FL_CALLOC(H5S_t))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - if (H5O_read(ent, H5O_SDSPACE_ID, 0, &(ds->extent.u.simple), dxpl_id) == NULL) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to load dataspace info from dataset header"); - - if(ds->extent.u.simple.rank != 0) { - hsize_t nelem; /* Number of elements in extent */ - unsigned u; /* Local index variable */ + if (H5O_read(ent, H5O_SDSPACE_NEW_ID, 0, &(ds->extent), dxpl_id) != NULL) { /* New data space header message */ + switch(ds->extent.type) { + case H5S_NULL: + ds->extent.nelem = 0; + if(H5S_select_none(ds)<0) + HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set none selection"); + ds->select.offset = NULL; + break; - ds->extent.type = H5S_SIMPLE; + case H5S_SCALAR: + ds->extent.nelem = 1; + /* Default to entire dataspace being selected */ + if(H5S_select_all(ds,0)<0) + HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection"); + ds->select.offset = NULL; + break; + + case H5S_SIMPLE: { + hsize_t nelem; /* Number of elements in extent */ + unsigned u; /* Local index variable */ + + /* Compute the number of elements in the extent */ + for(u=0, nelem=1; uextent.u.simple.rank; u++) + nelem*=ds->extent.u.simple.size[u]; + ds->extent.nelem = nelem; + + /* Default to entire dataspace being selected */ + if(H5S_select_all(ds,0)<0) + HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection"); + + /* Allocate space for the offset and set it to zeros */ + if (NULL==(ds->select.offset = H5FL_ARR_CALLOC(hssize_t,ds->extent.u.simple.rank))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - /* Compute the number of elements in the extent */ - for(u=0, nelem=1; uextent.u.simple.rank; u++) - nelem*=ds->extent.u.simple.size[u]; - ds->extent.nelem = nelem; - } /* end if */ -/* How to distinguish between H5S_SCALAR and H5S_NULL? */ - else { - ds->extent.type = H5S_SCALAR; - ds->extent.nelem = 1; - } /* end else */ + break; } + + default: + HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unknown data space type"); + } + } else { /* For backward compatibility, if file is created by version 1.6 or before. */ + if (H5O_read(ent, H5O_SDSPACE_ID, 0, &(ds->extent.u.simple), dxpl_id) == NULL) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to load dataspace info from dataset header"); + + if(ds->extent.u.simple.rank != 0) { + hsize_t nelem; /* Number of elements in extent */ + unsigned u; /* Local index variable */ + + ds->extent.type = H5S_SIMPLE; + + /* Compute the number of elements in the extent */ + for(u=0, nelem=1; uextent.u.simple.rank; u++) + nelem*=ds->extent.u.simple.size[u]; + ds->extent.nelem = nelem; + } else { + ds->extent.type = H5S_SCALAR; + ds->extent.nelem = 1; + } /* end if */ - /* Default to entire dataspace being selected */ - if(H5S_select_all(ds,0)<0) - HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection"); + /* Default to entire dataspace being selected */ + if(H5S_select_all(ds,0)<0) + HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection"); - /* Allocate space for the offset and set it to zeros */ - if(ds->extent.u.simple.rank>0) { - if (NULL==(ds->select.offset = H5FL_ARR_CALLOC(hssize_t,ds->extent.u.simple.rank))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + /* Allocate space for the offset and set it to zeros */ + if(ds->extent.u.simple.rank>0) { + if (NULL==(ds->select.offset = H5FL_ARR_CALLOC(hssize_t,ds->extent.u.simple.rank))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + } else + ds->select.offset = NULL; } /* end if */ - else - ds->select.offset = NULL; - + /* Set the value for successful return */ ret_value=ds; @@ -1415,7 +1495,7 @@ H5S_set_extent_simple (H5S_t *space, unsigned rank, const hsize_t *dims, else space->select.offset = NULL; - /* shift out of the previous state to a "simple" dataspace */ + /* shift out of the previous state to a "simple" dataspace. Not valid for H5S_NULL */ switch (space->extent.type) { case H5S_SCALAR: /* do nothing */ @@ -2085,7 +2165,9 @@ H5S_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *stream, int indent, case H5S_SIMPLE: fprintf(stream, "%*s%-*s H5S_SIMPLE\n", indent, "", fwidth, "Space class:"); - H5O_debug_id(H5O_SDSPACE_ID, f, dxpl_id, &(mesg->extent.u.simple), stream, + /*H5O_debug_id(H5O_SDSPACE_ID, f, dxpl_id, &(mesg->extent.u.simple), stream, + indent+3, MAX(0, fwidth-3));*/ + H5O_debug_id(H5O_SDSPACE_NEW_ID, f, dxpl_id, &(mesg->extent), stream, indent+3, MAX(0, fwidth-3)); break; diff --git a/src/H5Sall.c b/src/H5Sall.c index f03dbcd..fac8d96 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -708,6 +708,10 @@ H5S_select_all (H5S_t *space, unsigned rel_prev) /* Check args */ assert(space); + + /* Not valid for H5S_NULL dataspace */ + if (space->extent.type == H5S_NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid data space"); /* Remove current selection first */ if(rel_prev) @@ -763,6 +767,7 @@ herr_t H5Sselect_all (hid_t spaceid) if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space"); + /* Not valid for H5S_NULL dataspace */ if (space->extent.type == H5S_NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a valid data space"); diff --git a/src/H5Snone.c b/src/H5Snone.c index e07f5ae..f91ef2f 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -665,8 +665,8 @@ herr_t H5S_select_none (H5S_t *space) /* Check args */ assert(space); - /* Remove current selection first */ - if((*space->select.release)(space)<0) + /* Remove current selection first. NULL data space either has no selection or selection is none. */ + if((space->extent.type != H5S_NULL) && (*space->select.release)(space)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab"); /* Set selection type */ diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 5d73fa2..5670f22 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -174,13 +174,14 @@ typedef struct { /* Main dataspace structure (typedef'd in H5Sprivate.h) */ struct H5S_t { - H5S_extent_t extent; /* Dataspace extent */ + H5S_extent_t extent; /* Dataspace extent */ H5S_select_t select; /* Dataspace selection */ }; /* Extent functions */ H5_DLL herr_t H5S_close_simple(H5S_simple_t *simple); H5_DLL herr_t H5S_release_simple(H5S_simple_t *simple); +H5_DLL herr_t H5S_release_extent(H5S_extent_t *extent); H5_DLL herr_t H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src); /* Operations on selections */ -- cgit v0.12