summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rw-r--r--src/H5Dlayout.c12
-rw-r--r--src/H5Dpkg.h5
-rw-r--r--src/H5Dprivate.h5
-rw-r--r--src/H5Dpublic.h1
-rw-r--r--src/H5Olayout.c222
-rw-r--r--src/H5Oprivate.h27
-rw-r--r--src/H5Pdcpl.c121
-rw-r--r--src/H5R.c4
-rw-r--r--src/H5S.c4
-rw-r--r--src/H5Sall.c41
-rw-r--r--src/H5Shyper.c80
-rw-r--r--src/H5Snone.c36
-rw-r--r--src/H5Spkg.h2
-rw-r--r--src/H5Spoint.c62
-rw-r--r--src/H5Sselect.c20
-rw-r--r--src/Makefile.am2
17 files changed, 559 insertions, 86 deletions
diff --git a/MANIFEST b/MANIFEST
index fbc4a1e..a0737ef 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -615,6 +615,7 @@
./src/H5Dscatgath.c
./src/H5Dselect.c
./src/H5Dtest.c
+./src/H5Dvirtual.c
./src/H5E.c
./src/H5Edefin.h
./src/H5Edeprec.c
diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c
index d7d7b88..5929163 100644
--- a/src/H5Dlayout.c
+++ b/src/H5Dlayout.c
@@ -104,6 +104,10 @@ H5D__layout_set_io_ops(const H5D_t *dataset)
dataset->shared->layout.ops = H5D_LOPS_COMPACT;
break;
+ case H5D_VIRTUAL:
+ dataset->shared->layout.ops = H5D_LOPS_VIRTUAL;
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -169,6 +173,11 @@ H5D__layout_meta_size(const H5F_t *f, const H5O_layout_t *layout, hbool_t includ
ret_value += H5F_SIZEOF_ADDR(f); /* Address of data */
break;
+ case H5D_VIRTUAL:
+ ret_value += H5F_SIZEOF_ADDR(f); /* Address of global heap */
+ ret_value += 4; /* Global heap index */
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -439,6 +448,9 @@ H5D__layout_oh_read(H5D_t *dataset, hid_t dxpl_id, hid_t dapl_id, H5P_genplist_t
case H5D_COMPACT:
break;
+ case H5D_VIRTUAL:
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index 5a785a3..1a659a1 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -173,11 +173,15 @@ typedef struct {
hbool_t *dirty; /* Pointer to dirty flag to mark */
} H5D_compact_storage_t;
+typedef struct {
+} H5D_virtual_storage_t;
+
typedef union H5D_storage_t {
H5D_contig_storage_t contig; /* Contiguous information for dataset */
H5D_chunk_storage_t chunk; /* Chunk information for dataset */
H5D_compact_storage_t compact; /* Compact information for dataset */
H5O_efl_t efl; /* External file list information for dataset */
+ H5D_virtual_storage_t virtual; /* Virtual dataset information */
} H5D_storage_t;
/* Typedef for raw data I/O operation info */
@@ -515,6 +519,7 @@ H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CONTIG[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_EFL[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_COMPACT[1];
H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CHUNK[1];
+H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_VIRTUAL[1];
/* Chunked layout operations */
H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_BTREE[1];
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index 0b8b76f..804afd1 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -174,6 +174,11 @@ H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id,
/* Functions that operate on chunked storage */
H5_DLL herr_t H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr);
+/* Functions that operate on virtual storage */
+herr_t H5D_virtual_copy_layout(H5O_layout_t *layout);
+herr_t H5D__virtual_delete(H5F_t *f, hid_t dxpl_id,
+ const H5O_storage_t *storage);
+
/* Functions that operate on indexed storage */
H5_DLL herr_t H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
int indent, int fwidth, unsigned ndims);
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index e7ae3ae..003e357 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -51,6 +51,7 @@ typedef enum H5D_layout_t {
H5D_COMPACT = 0, /*raw data is very small */
H5D_CONTIGUOUS = 1, /*the default */
H5D_CHUNKED = 2, /*slow and fancy */
+ H5D_VIRTUAL = 3, /*actual data is stored in other datasets */
H5D_NLAYOUTS = 3 /*this one must be last! */
} H5D_layout_t;
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 4c43873..2b12a97 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -96,10 +96,11 @@ H5FL_DEFINE(H5O_layout_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
+H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
H5O_layout_t *mesg = NULL;
+ uint8_t *heap_block = NULL;
unsigned u;
void *ret_value; /* Return value */
@@ -241,6 +242,72 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
mesg->ops = H5D_LOPS_CHUNK;
break;
+ case H5D_VIRTUAL:
+ /* Heap information */
+ H5F_addr_decode(f, &p, &(mesg->storage.u.virtual.serial_list_hobjid.addr));
+ UINT32DECODE(p, mesg->storage.u.virtual.serial_list_hobjid.idx);
+
+ /* Initialize other fields */
+ mesg->storage.u.virtual.list_nused = 0;
+ mesg->storage.u.virtual.list = NULL;
+ mesg->storage.u.virtual.list_nalloc = 0;
+
+ /* Decode heap block if it exists */
+ if(mesg->storage.u.virtual.serial_list_hobjid.addr != HADDR_UNDEF) {
+ uint8_t *heap_block_p;
+ size_t block_size = 0;
+ hsize_t tmp_hsize;
+ uint32_t stored_chksum;
+ uint32_t computed_chksum;
+ size_t i;
+
+ /* Read heap */
+ if(NULL == (heap_block = (uint8_t *)H5HG_read(f, dxpl_id, &(mesg->storage.u.virtual.serial_list_hobjid), NULL, &block_size)))
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "Unable to read global heap block")
+
+ heap_block_p = heap_block;
+
+ /* Number of entries */
+ H5F_DECODE_LENGTH(f, heap_block_p, tmp_hsize)
+
+ /* Allocate entry list */
+ if(NULL == (mesg->storage.u.virtual.list = (H5O_storage_virtual_ent_t *)H5MM_malloc((size_t)tmp_hsize * sizeof(H5O_storage_virtual_ent_t))))
+ HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to allocate heap block")
+ mesg->storage.u.virtual.list_nalloc = (size_t)tmp_hsize;
+ mesg->storage.u.virtual.list_nused = (size_t)tmp_hsize;
+
+ /* Decode each entry */
+ for(i = 0; i < mesg->storage.u.virtual.list_nused; i++) {
+ /* Source file name */
+ if(NULL == (mesg->storage.u.virtual.list[i].source_file = HDstrdup(heap_block_p)))
+ HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to duplicate source file name")
+ heap_block_p += HDstrlen(heap_block_p) + 1;
+
+ /* Source dataset name */
+ if(NULL == (mesg->storage.u.virtual.list[i].source_dset = HDstrdup(heap_block_p)))
+ HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, NULL, "unable to duplicate source dataset name")
+ heap_block_p += HDstrlen(heap_block_p) + 1;
+
+ /* Source selection */
+ H5S_SELECT_DESERIALIZE(&(mesg->storage.u.virtual.list[i].source_select), &heap_block_p)
+
+ /* Virtual selection */
+ H5S_SELECT_SERIALIZE(&(mesg->storage.u.virtual.list[i].virtual_select), &heap_block_p)
+ } /* end for */
+
+ /* Read stored checksum */
+ UINT32DECODE(heap_block_p, stored_chksum)
+
+ /* Compute checksum */
+ computed_chksum = H5_checksum_metadata(heap_block, block_size - (size_t)4, 0);
+
+ /* Verify checksum */
+ if(stored_chksum != computed_chksum)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect metadata checksum for global heap block")
+ } /* end if */
+
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -253,9 +320,13 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh,
done:
if(ret_value == NULL)
- if(mesg)
+ if(mesg) {
+ if(mesg->type == H5D_VIRTUAL)
+ mesg->
mesg = H5FL_FREE(H5O_layout_t, mesg);
+ heap_block = H5MM_xfree(heap_block);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_layout_decode() */
@@ -294,6 +365,7 @@ static herr_t
H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const void *_mesg)
{
const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg;
+ uint8_t *heap_block = NULL;
unsigned u;
herr_t ret_value = SUCCEED; /* Return value */
@@ -344,6 +416,101 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi
UINT32ENCODE(p, mesg->u.chunk.dim[u]);
break;
+ case H5D_VIRTUAL:
+ /* Create heap block if it has not been created yet */
+ /* Note that we assume here that the contents of the heap block
+ * cannot change! If this ever stops being the case we must change
+ * this code to allow overwrites of the heap block. -NAF */
+ if((mesg->storage.u.virtual.serial_list_hobjid.addr == HADDR_UNDEF)
+ && (mesg->storage.u.virtual.list_nused > 0)) {
+ uint8_t *heap_block_p;
+ size_t block_size;
+ hssize_t select_serial_size;
+ hsize_t tmp_hsize;
+ uint32_t chksum;
+ size_t i;
+
+ /*
+ * Calculate heap block size
+ */
+ /* Number of entries */
+ block_size = H5F_SIZEOF_SIZE(f);
+
+ /* Calculate size of each entry */
+ for(i = 0; i < mesg->storage.u.virtual.list_nused; i++) {
+ HDassert(mesg->storage.u.virtual.list[i].source_file);
+ HDassert(mesg->storage.u.virtual.list[i].source_dset);
+ HDassert(mesg->storage.u.virtual.list[i].source_select);
+ HDassert(mesg->storage.u.virtual.list[i].virtual_select);
+
+ /* Source file name */
+ block_size += HDstrlen(mesg->storage.u.virtual.list[i].source_file) + (size_t)1;
+
+ /* Source dset name */
+ block_size += HDstrlen(mesg->storage.u.virtual.list[i].source_dset) + (size_t)1;
+
+ /* Source selection */
+ if((select_serial_size = H5S_SELECT_SERIAL_SIZE(mesg->storage.u.virtual.list[i].source_select)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to check dataspace selection size")
+ block_size += (size_t)select_serial_size;
+
+ /* Virtual dataset selection */
+ if((select_serial_size = H5S_SELECT_SERIAL_SIZE(mesg->storage.u.virtual.list[i].virtual_select)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to check dataspace selection size")
+ block_size += (size_t)select_serial_size;
+ } /* end for */
+
+ /* Checksum */
+ block_size += 4;
+
+ /* Allocate heap block */
+ if(NULL == (heap_block = (uint8_t *)H5MM_malloc((size_t)mesg->storage.u.virtual.serial_list_size)))
+ HGOTO_ERROR(H5E_OHDR, H5E_RESOURCE, FAIL, "unable to allocate heap block")
+
+ /*
+ * Encode heap block
+ */
+ heap_block_p = heap_block;
+
+ /* Number of entries */
+ tmp_hsize = (hsize_t)mesg->storage.u.virtual.list_nused;
+ H5F_ENCODE_LENGTH(f, heap_block_p, tmp_hsize)
+
+ /* Encode each entry */
+ for(i = 0; i < mesg->storage.u.virtual.list_nused; i++) {
+ /* Source file name */
+ (void)HDstrcpy(heap_block_p, mesg->storage.u.virtual.list[i].source_file);
+ heap_block_p += HDstrlen(heap_block_p) + 1;
+
+ /* Source dataset name */
+ (void)HDstrcpy(heap_block_p, mesg->storage.u.virtual.list[i].source_dset);
+ heap_block_p += HDstrlen(heap_block_p) + 1;
+
+ /* Source selection */
+ if(H5S_SELECT_SERIALIZE(mesg->storage.u.virtual.list[i].source_select, &heap_block_p) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to serialize selection")
+
+ /* Virtual selection */
+ if(H5S_SELECT_SERIALIZE(mesg->storage.u.virtual.list[i].virtual_select, &heap_block_p) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to serialize selection")
+ } /* end for */
+
+ /* Checksum */
+ chksum = H5_checksum_metadata(heap_block, block_size - (size_t)4, 0);
+ UINT32ENCODE(heap_block_p, chksum)
+
+ /* Insert block into global heap */
+ /* Casting away const OK --NAF */
+ if(H5HG_insert(f, H5AC_ind_dxpl_id, block_size, heap_block, &((H5O_layout_t *)mesg)->storage.u.virtual.serial_list_hobjid) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to insert virtual dataset heap block")
+ } /* end if */
+
+ /* Heap information */
+ H5F_addr_encode(f, &p, mesg->storage.u.virtual.serial_list_hobjid.addr);
+ UINT32ENCODE(p, mesg->storage.u.virtual.serial_list_hobjid.idx);
+
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -351,6 +518,8 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi
} /* end switch */
done:
+ heap_block = H5MM_xfree(heap_block);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_layout_encode() */
@@ -403,6 +572,11 @@ H5O_layout_copy(const void *_mesg, void *_dest)
if(dest->type == H5D_CHUNKED && dest->storage.u.chunk.ops)
H5D_chunk_idx_reset(&dest->storage.u.chunk, FALSE);
+ /* Deep copy the entry list for virtual datasets */
+ if(mesg->type == H5D_VIRTUAL)
+ if(H5D_virtual_copy_layout(dest) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy virtual layout")
+
/* Set return value */
ret_value = dest;
@@ -468,19 +642,43 @@ static herr_t
H5O_layout_reset(void *_mesg)
{
H5O_layout_t *mesg = (H5O_layout_t *)_mesg;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_NOAPI_NOINIT
if(mesg) {
/* Free the compact storage buffer */
if(H5D_COMPACT == mesg->type)
mesg->storage.u.compact.buf = H5MM_xfree(mesg->storage.u.compact.buf);
+ /* Free the virtual entry list */
+ if(H5D_VIRTUAL == mesg->type) {
+ if(mesg->storage.u.virtual.list_nused > 0) {
+ size_t i;
+ HDassert(mesg->storage.u.virtual.list);
+
+ /* Free the list entries */
+ for(i = 0; i < mesg->storage.u.virtual.nused; i++) {
+ mesg->storage.u.virtual.list[i].source_file = H5MM_xfree(mesg->storage.u.virtual.list[i].source_file);
+ mesg->storage.u.virtual.list[i].source_dset = H5MM_xfree(mesg->storage.u.virtual.list[i].source_dset);
+ if(H5S_close(mesg->storage.u.virtual.list[i].source_select) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CLOSEERROR, FAIL, "unable to release source selection")
+ mesg->storage.u.virtual.list[i].source_select = NULL;
+ if(H5S_close(mesg->storage.u.virtual.list[i].virtual_select) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CLOSEERROR, FAIL, "unable to release virtual selection")
+ mesg->storage.u.virtual.list[i].virtual_select = NULL;
+ } /* end for */
+
+ /* Free the list */
+ mesg->storage.u.virtual.list = H5MM_xfree(mesg->storage.u.virtual.list);
+ } /* end if */
+
/* Reset the message */
mesg->type = H5D_CONTIGUOUS;
} /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_layout_reset() */
@@ -560,6 +758,13 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg)
HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data")
break;
+ case H5D_VIRTUAL: /* Virtual dataset */
+ HDassert(0 && "checking code coverage...");//VDSINC
+ /* Free the file space virtual dataset */
+ if(H5D__virtual_delete(f, dxpl_id, &mesg->storage) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data")
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -647,6 +852,10 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
} /* end if */
break;
+ case H5D_VIRTUAL:
+ HDassert(0 && "Not yet implemented...");//VDSINC
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -745,6 +954,11 @@ H5O_layout_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg,
"Data Size:", mesg->storage.u.compact.size);
break;
+ case H5D_VIRTUAL:
+ HDassert(0 && "Not yet implemented...");//VDSINC
+
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index e3a2d33..b3d6237 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -372,7 +372,8 @@ typedef struct H5O_efl_t {
* for larger chunk dimensions, stores chunk indices into their own
* message (the "layout index" message), adds features for compact/dense
* storage of elements and/or chunk records, adds features for abbreviating
- * the storage used for partial chunks on boundaries, etc.
+ * the storage used for partial chunks on boundaries, adds the virtual
+ * layout type, etc.
*/
#define H5O_LAYOUT_VERSION_4 4
@@ -410,12 +411,36 @@ typedef struct H5O_storage_compact_t {
void *buf; /* Buffer for compact dataset */
} H5O_storage_compact_t;
+typedef struct H5O_storage_virtual_ent_t {
+ /* Stored */
+ char *source_file;
+ char *source_dset;
+ H5S_t *source_select;
+ H5S_t *virtual_select;
+
+ /* Not stored */
+ H5D_t *source_dset;
+} H5O_storage_virtual_ent_t;
+
+typedef struct H5O_storage_virtual_t {
+ /* Stored in message */
+ H5HG_t serial_list_hobjid;
+
+ /* Stored in heap */
+ size_t list_nused; /* Number of slots used */
+ H5O_storage_virtual_ent_t *list; /* Array of virtual dataset mapping entries */
+
+ /* Not stored */
+ size_t list_nalloc; /* Number of slots allocated */
+} H5O_storage_virtual_t;
+
typedef struct H5O_storage_t {
H5D_layout_t type; /* Type of layout */
union {
H5O_storage_contig_t contig; /* Information for contiguous storage */
H5O_storage_chunk_t chunk; /* Information for chunked storage */
H5O_storage_compact_t compact; /* Information for compact storage */
+ H5O_storage_virtual_t virtual; /* Information for virtual storage */
} u;
} H5O_storage_t;
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index a753209..e9bd9bf 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -41,6 +41,7 @@
#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
+#include "H5Oprivate.h" /* Object headers */
#include "H5Ppkg.h" /* Property lists */
#include "H5Tprivate.h" /* Datatypes */
#include "H5Zpkg.h" /* Data filters */
@@ -55,13 +56,16 @@
#define H5D_DEF_STORAGE_CONTIG_INIT {HADDR_UNDEF, (hsize_t)0}
#define H5D_DEF_STORAGE_CHUNK_INIT {H5D_CHUNK_BTREE, HADDR_UNDEF, NULL, {{HADDR_UNDEF, NULL}}}
#define H5D_DEF_LAYOUT_CHUNK_INIT {(unsigned)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, (uint32_t)0, (hsize_t)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
+#define H5D_DEF_STORAGE_VIRTUAL_INIT {{HADDR_UNDEF, 0}, 0, NULL, 0}
#ifdef H5_HAVE_C99_DESIGNATED_INITIALIZER
#define H5D_DEF_STORAGE_COMPACT {H5D_COMPACT, { .compact = H5D_DEF_STORAGE_COMPACT_INIT }}
#define H5D_DEF_STORAGE_CONTIG {H5D_CONTIGUOUS, { .contig = H5D_DEF_STORAGE_CONTIG_INIT }}
#define H5D_DEF_STORAGE_CHUNK {H5D_CHUNKED, { .chunk = H5D_DEF_STORAGE_CHUNK_INIT }}
-#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_COMPACT}
+#define H5D_DEF_STORAGE_VIRTUAL {H5D_CHUNKED, { .chunk = H5D_DEF_STORAGE_CHUNK_INIT }}
+#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_VIRTUAL}
#define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CONTIG}
#define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CHUNK}
+#define H5D_DEF_LAYOUT_VIRTUAL {H5D_VIRTUAL, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_VIRTUAL}
#else /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
/* Note that the compact & chunked layout initialization values are using the
* contiguous layout initialization in the union, because the contiguous
@@ -71,6 +75,7 @@
#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
+#define H5D_DEF_LAYOUT_VIRTUAL {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
/* ======== Dataset creation properties ======== */
@@ -79,7 +84,10 @@
#define H5D_CRT_LAYOUT_DEF H5D_DEF_LAYOUT_CONTIG
#define H5D_CRT_LAYOUT_ENC H5P__dcrt_layout_enc
#define H5D_CRT_LAYOUT_DEC H5P__dcrt_layout_dec
+#define H5D_CRT_LAYOUT_DEL H5P__dcrt_layout_del
+#define H5D_CRT_LAYOUT_COPY H5P__dcrt_layout_copy
#define H5D_CRT_LAYOUT_CMP H5P__dcrt_layout_cmp
+#define H5D_CRT_LAYOUT_CLOSE H5P__dcrt_layout_close
/* Definitions for fill value. size=0 means fill value will be 0 as
* library default; size=-1 means fill value is undefined. */
#define H5D_CRT_FILL_VALUE_SIZE sizeof(H5O_fill_t)
@@ -183,10 +191,12 @@ static const H5O_efl_t H5D_def_efl_g = H5D_CRT_EXT_FILE_LIST_DEF;
static const H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT;
static const H5O_layout_t H5D_def_layout_contig_g = H5D_DEF_LAYOUT_CONTIG;
static const H5O_layout_t H5D_def_layout_chunk_g = H5D_DEF_LAYOUT_CHUNK;
+static const H5O_layout_t H5D_def_layout_virtual_g = H5D_DEF_LAYOUT_VIRTUAL;
#else /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
static H5O_layout_t H5D_def_layout_compact_g = H5D_DEF_LAYOUT_COMPACT;
static H5O_layout_t H5D_def_layout_contig_g = H5D_DEF_LAYOUT_CONTIG;
static H5O_layout_t H5D_def_layout_chunk_g = H5D_DEF_LAYOUT_CHUNK;
+static H5O_layout_t H5D_def_layout_virtual_g = H5D_DEF_LAYOUT_CHUNK;
static hbool_t H5P_dcrt_def_layout_init_g = FALSE;
#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
@@ -213,7 +223,7 @@ H5P__dcrt_reg_prop(H5P_genclass_t *pclass)
/* Register the storage layout property */
if(H5P_register_real(pclass, H5D_CRT_LAYOUT_NAME, H5D_CRT_LAYOUT_SIZE, &H5D_def_layout_g,
NULL, NULL, NULL, H5D_CRT_LAYOUT_ENC, H5D_CRT_LAYOUT_DEC,
- NULL, NULL, H5D_CRT_LAYOUT_CMP, NULL) < 0)
+ H5D_CRT_LAYOUT_DEL, H5D_CRT_LAYOUT_COPY, H5D_CRT_LAYOUT_CMP, H5D_CRT_LAYOUT_CLOSE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
/* Register the fill value property */
@@ -444,6 +454,9 @@ H5P__dcrt_layout_enc(const void *value, void **_pp, size_t *size)
for(u = 0; u < layout->u.chunk.ndims; u++)
UINT32ENCODE(*pp, layout->u.chunk.dim[u])
} /* end if */
+ else if(H5D_VIRTUAL == layout->type) {
+ HDassert(0 && "Not yet implemented...");//VDSINC
+ } /* end else */
} /* end if */
/* Size of layout type */
@@ -531,6 +544,10 @@ H5P__dcrt_layout_dec(const void **_pp, void *value)
}
break;
+ case H5D_VIRTUAL:
+ HDassert(0 && "Not yet implemented...");//VDSINC
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -546,6 +563,66 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5P__dcrt_layout_del
+ *
+ * Purpose: Frees memory used to store the layout property
+ *
+ * Return: Success: Non-negative
+ * Failure: Never fails
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, Feb 10, 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__dcrt_layout_del(hid_t UNUSED prop_id, const char UNUSED *name, size_t UNUSED size, void *value)
+{
+ FUNC_ENTER_STATIC_NOERR
+
+ HDassert(value);
+
+ (void)H5O_msg_free(H5O_LAYOUT_ID, value)
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__dcrt_layout_del() */
+
+
+/*--------------------------------------------------------------------------
+ * Function: H5P__dcrt_layout_copy
+ *
+ * Purpose: Copy the layout property
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Monday, Feb 9, 2015
+ *
+ *--------------------------------------------------------------------------
+ */
+static herr_t
+H5P__dcrt_layout_copy(const char UNUSED *name, size_t UNUSED size, void *value)
+{
+ H5O_layout_t *layout;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_STATIC
+
+ HDassert(value);
+
+ layout = (H5O_layout_t *)value;
+
+ if(layout->type == H5D_VIRTUAL)
+ if(H5D_virtual_copy_layout(layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual layout")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__dcrt_layout_copy() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5P__dcrt_layout_cmp
*
* Purpose: Callback routine which is called whenever the layout
@@ -605,6 +682,10 @@ H5P__dcrt_layout_cmp(const void *_layout1, const void *_layout2, size_t UNUSED s
} /* end case */
break;
+ case H5D_VIRTUAL:
+ HDassert(0 && "Not yet implemented...");//VDSINC
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -617,6 +698,32 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5P__dcrt_layout_close
+ *
+ * Purpose: Frees memory used to store the layout property
+ *
+ * Return: Success: Non-negative
+ * Failure: Never fails
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, Feb 10, 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5P__dcrt_layout_close(const char UNUSED *name, size_t UNUSED size, void *value)
+{
+ FUNC_ENTER_STATIC_NOERR
+
+ HDassert(value);
+
+ (void)H5O_msg_free(H5O_LAYOUT_ID, value)
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__dcrt_layout_close() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5P__fill_value_enc
*
* Purpose: Callback routine which is called whenever the fill value
@@ -1141,6 +1248,10 @@ H5P__set_layout(H5P_genplist_t *plist, const H5O_layout_t *layout)
fill.alloc_time = H5D_ALLOC_TIME_INCR;
break;
+ case H5D_VIRTUAL:
+ fill.alloc_time = H5D_ALLOC_TIME_INCR;
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
@@ -1181,6 +1292,7 @@ H5P__init_def_layout(void)
const H5O_layout_chunk_t def_layout_chunk = H5D_DEF_LAYOUT_CHUNK_INIT;
const H5O_storage_compact_t def_store_compact = H5D_DEF_STORAGE_COMPACT_INIT;
const H5O_storage_chunk_t def_store_chunk = H5D_DEF_STORAGE_CHUNK_INIT;
+ const H5O_storage_virtual_t def_store_virtual = H5D_DEF_STORAGE_VIRTUAL_INIT;
FUNC_ENTER_STATIC_NOERR
@@ -1188,6 +1300,7 @@ H5P__init_def_layout(void)
H5D_def_layout_compact_g.storage.u.compact = def_store_compact;
H5D_def_layout_chunk_g.u.chunk = def_layout_chunk;
H5D_def_layout_chunk_g.storage.u.chunk = def_store_chunk;
+ H5D_def_layout_virtual_g.storage.u.virtual = def_store_virtual;
/* Note that we've initialized the default values */
H5P_dcrt_def_layout_init_g = TRUE;
@@ -1257,6 +1370,10 @@ H5Pset_layout(hid_t plist_id, H5D_layout_t layout_type)
layout = &H5D_def_layout_chunk_g;
break;
+ case H5D_VIRTUAL:
+ layout = &H5D_def_layout_virtual_g;
+ break;
+
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
default:
diff --git a/src/H5R.c b/src/H5R.c
index 8396dcc..f44b21f 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -291,7 +291,7 @@ H5R_create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5
H5F_addr_encode(loc->oloc->file, &p, obj_loc.oloc->addr);
/* Serialize the selection into heap buffer */
- if(H5S_SELECT_SERIALIZE(space, p) < 0)
+ if(H5S_SELECT_SERIALIZE(space, &p) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection")
/* Save the serialized buffer for later */
@@ -659,7 +659,7 @@ H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref)
HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found")
/* Unserialize the selection */
- if(H5S_select_deserialize(ret_value, p) < 0)
+ if(H5S_select_deserialize(&ret_value, &p) < 0)
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection")
done:
diff --git a/src/H5S.c b/src/H5S.c
index 1146ab4..7798049 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -1536,7 +1536,7 @@ H5S_encode(H5S_t *obj, unsigned char *buf, size_t *nalloc)
buf += extent_size;
/* Encode the selection part of dataspace. */
- if(H5S_SELECT_SERIALIZE(obj, buf) < 0)
+ if(H5S_SELECT_SERIALIZE(obj, &buf) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode select space")
} /* end else */
@@ -1655,7 +1655,7 @@ H5S_decode(const unsigned char *buf)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection")
/* Decode the select part of dataspace. I believe this part always exists. */
- if(H5S_SELECT_DESERIALIZE(ds, buf) < 0)
+ if(H5S_SELECT_DESERIALIZE(&ds, &buf) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDECODE, NULL, "can't decode space selection")
/* Set return value */
diff --git a/src/H5Sall.c b/src/H5Sall.c
index 24caad2..a9e72fb 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -510,17 +510,19 @@ H5S_all_serial_size (const H5S_t UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_all_serialize (const H5S_t *space, uint8_t *buf)
+H5S_all_serialize (const H5S_t *space, uint8_t **p)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
+ HDassert(p);
+ HDassert(*p);
/* Store the preamble information */
- UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
- UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */
- UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */
- UINT32ENCODE(buf, (uint32_t)0); /* Store the additional information length */
+ UINT32ENCODE(*p, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
+ UINT32ENCODE(*p, (uint32_t)1); /* Store the version number */
+ UINT32ENCODE(*p, (uint32_t)0); /* Store the un-used padding */
+ UINT32ENCODE(*p, (uint32_t)0); /* Store the additional information length */
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_all_serialize() */
@@ -546,19 +548,42 @@ H5S_all_serialize (const H5S_t *space, uint8_t *buf)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_all_deserialize(H5S_t *space, const uint8_t UNUSED *buf)
+H5S_all_deserialize(H5S_t **space, const uint8_t **p)
{
- herr_t ret_value; /* return value */
+ H5S_t *tmp_space;
+ herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_NOAPI(FAIL)
HDassert(space);
+ HDassert(p);
+ HDassert(*p);
+
+ /* Allocate space if not provided */
+ if(!*space) {
+ if(NULL == (tmp_space = H5S_create(H5S_SIMPLE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace")
+ } /* end if */
+ else
+ tmp_space = *space;
+
+
+ /* Skip over the remainder of the header */
+ *p += 12;
/* Change to "all" selection */
- if((ret_value = H5S_select_all(space, TRUE)) < 0)
+ if(H5S_select_all(tmp_space, TRUE) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ if(!*space)
+ *space = tmp_space;
+
done:
+ /* Free temporary space if not passed to caller (only happens on error) */
+ if(!*space && tmp_space)
+ if(H5S_close(tmp_space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_all_deserialize() */
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index c97c9b6..02d9359 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -1994,7 +1994,7 @@ H5S_hyper_serial_size(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **buf)
+H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **p)
{
H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */
hsize_t u; /* Index variable */
@@ -2007,7 +2007,7 @@ H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start,
HDassert(start);
HDassert(end);
HDassert(rank < H5O_LAYOUT_NDIMS);
- HDassert(buf && *buf);
+ HDassert(p && *p);
/* Walk through the list of spans, recursing or outputing them */
curr=spans->head;
@@ -2019,7 +2019,7 @@ H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start,
end[rank]=curr->high;
/* Recurse down to the next dimension */
- if(H5S_hyper_serialize_helper(curr->down,start,end,rank+1,buf)<0)
+ if(H5S_hyper_serialize_helper(curr->down,start,end,rank+1,p)<0)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans")
} /* end if */
else {
@@ -2027,17 +2027,17 @@ H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start,
/* Encode previous starting points */
for(u=0; u<rank; u++)
- UINT32ENCODE(*buf, (uint32_t)start[u]);
+ UINT32ENCODE(*p, (uint32_t)start[u]);
/* Encode starting point for this span */
- UINT32ENCODE(*buf, (uint32_t)curr->low);
+ UINT32ENCODE(*p, (uint32_t)curr->low);
/* Encode previous ending points */
for(u=0; u<rank; u++)
- UINT32ENCODE(*buf, (uint32_t)end[u]);
+ UINT32ENCODE(*p, (uint32_t)end[u]);
/* Encode starting point for this span */
- UINT32ENCODE(*buf, (uint32_t)curr->high);
+ UINT32ENCODE(*p, (uint32_t)curr->high);
} /* end else */
/* Advance to next node */
@@ -2069,7 +2069,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
+H5S_hyper_serialize (const H5S_t *space, uint8_t **p)
{
const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */
@@ -2089,11 +2089,11 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
HDassert(space);
/* Store the preamble information */
- UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
- UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */
- UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */
- lenp = buf; /* keep the pointer to the length location for later */
- buf += 4; /* skip over space for length */
+ UINT32ENCODE(*p, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
+ UINT32ENCODE(*p, (uint32_t)1); /* Store the version number */
+ UINT32ENCODE(*p, (uint32_t)0); /* Store the un-used padding */
+ lenp = *p; /* keep the pointer to the length location for later */
+ *p += 4; /* skip over space for length */
/* Encode number of dimensions */
UINT32ENCODE(buf, (uint32_t)space->extent.rank);
@@ -2114,7 +2114,7 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
/* Encode number of hyperslabs */
H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t);
- UINT32ENCODE(buf, (uint32_t)block_count);
+ UINT32ENCODE(*p, (uint32_t)block_count);
len+=4;
/* Now serialize the information for the regular hyperslab */
@@ -2137,11 +2137,11 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
/* Encode hyperslab starting location */
for(u = 0; u < ndims; u++)
- UINT32ENCODE(buf, (uint32_t)offset[u]);
+ UINT32ENCODE(*p, (uint32_t)offset[u]);
/* Encode hyperslab ending location */
for(u = 0; u < ndims; u++)
- UINT32ENCODE(buf, (uint32_t)(offset[u] + (diminfo[u].block - 1)));
+ UINT32ENCODE(*p, (uint32_t)(offset[u] + (diminfo[u].block - 1)));
/* Move the offset to the next sequence to start */
offset[fast_dim]+=diminfo[fast_dim].stride;
@@ -2192,7 +2192,7 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
/* Encode number of hyperslabs */
block_count = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst);
H5_CHECK_OVERFLOW(block_count, hsize_t, uint32_t);
- UINT32ENCODE(buf, (uint32_t)block_count);
+ UINT32ENCODE(*p, (uint32_t)block_count);
len+=4;
/* Add 8 bytes times the rank for each hyperslab selected */
@@ -2200,7 +2200,7 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
len += (size_t)(8 * space->extent.rank * block_count);
/* Encode each hyperslab in selection */
- H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &buf);
+ H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, p);
} /* end else */
/* Encode length */
@@ -2230,8 +2230,9 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf)
+H5S_hyper_deserialize (H5S_t **space, const uint8_t **p)
{
+ H5S_t *tmp_space;
uint32_t rank; /* rank of points */
size_t num_elem=0; /* number of elements in selection */
hsize_t start[H5O_LAYOUT_NDIMS]; /* hyperslab start information */
@@ -2251,14 +2252,29 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf)
/* Check args */
HDassert(space);
- HDassert(buf);
+ HDassert(p);
+ HDassert(*p);
/* Deserialize slabs to select */
- buf+=16; /* Skip over selection header */
- UINT32DECODE(buf,rank); /* decode the rank of the point selection */
- if(rank!=space->extent.rank)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace")
- UINT32DECODE(buf,num_elem); /* decode the number of points */
+ *p+=12; /* Skip over remainder of selection header */
+ UINT32DECODE(*p,rank); /* decode the rank of the point selection */
+ UINT32DECODE(*p,num_elem); /* decode the number of points */
+
+ /* Allocate space if not provided */
+ if(!*space) {
+ if(NULL == (tmp_space = H5S_create(H5S_SIMPLE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace")
+
+ /* Set rank of dataspace */
+ tmp_space->extent.rank = rank;
+ } /* end if */
+ else {
+ tmp_space = *space;
+
+ /* Verify rank of dataspace */
+ if(rank!=tmp_space->extent.rank)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace")
+ } /* end else */
/* Set the count & stride for all blocks */
for(tcount=count,tstride=stride,j=0; j<rank; j++,tstride++,tcount++) {
@@ -2270,22 +2286,30 @@ H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf)
for(i=0; i<num_elem; i++) {
/* Decode the starting points */
for(tstart=start,j=0; j<rank; j++,tstart++)
- UINT32DECODE(buf, *tstart);
+ UINT32DECODE(*p, *tstart);
/* Decode the ending points */
for(tend=end,j=0; j<rank; j++,tend++)
- UINT32DECODE(buf, *tend);
+ UINT32DECODE(*p, *tend);
/* Change the ending points into blocks */
for(tblock=block,tstart=start,tend=end,j=0; j<(unsigned)rank; j++,tstart++,tend++,tblock++)
*tblock=(*tend-*tstart)+1;
/* Select or add the hyperslab to the current selection */
- if((ret_value=H5S_select_hyperslab(space,(i==0 ? H5S_SELECT_SET : H5S_SELECT_OR),start,stride,count,block))<0)
+ if((ret_value=H5S_select_hyperslab(tmp_space,(i==0 ? H5S_SELECT_SET : H5S_SELECT_OR),start,stride,count,block))<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
} /* end for */
+ if(!*space)
+ *space = tmp_space;
+
done:
+ /* Free temporary space if not passed to caller (only happens on error) */
+ if(!*space && tmp_space)
+ if(H5S_close(tmp_space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_deserialize() */
diff --git a/src/H5Snone.c b/src/H5Snone.c
index 3c5eccc..a6c870a 100644
--- a/src/H5Snone.c
+++ b/src/H5Snone.c
@@ -478,17 +478,17 @@ H5S_none_serial_size(const H5S_t UNUSED *space)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_none_serialize(const H5S_t *space, uint8_t *buf)
+H5S_none_serialize(const H5S_t *space, uint8_t **p)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
/* Store the preamble information */
- UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
- UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */
- UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */
- UINT32ENCODE(buf, (uint32_t)0); /* Store the additional information length */
+ UINT32ENCODE(*p, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
+ UINT32ENCODE(*p, (uint32_t)1); /* Store the version number */
+ UINT32ENCODE(*p, (uint32_t)0); /* Store the un-used padding */
+ UINT32ENCODE(*p, (uint32_t)0); /* Store the additional information length */
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_none_serialize() */
@@ -514,19 +514,41 @@ H5S_none_serialize(const H5S_t *space, uint8_t *buf)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_none_deserialize(H5S_t *space, const uint8_t UNUSED *buf)
+H5S_none_deserialize(H5S_t **space, const uint8_t **p)
{
+ H5S_t *tmp_space;
herr_t ret_value = SUCCEED; /* return value */
FUNC_ENTER_NOAPI_NOINIT
HDassert(space);
+ HDassert(p);
+ HDassert(*p);
+
+ /* Allocate space if not provided */
+ if(!*space) {
+ if(NULL == (tmp_space = H5S_create(H5S_SIMPLE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace")
+ } /* end if */
+ else
+ tmp_space = *space;
+
+ /* Skip over the remainder of the header */
+ *p += 12;
/* Change to "none" selection */
- if(H5S_select_none(space) < 0)
+ if(H5S_select_none(tmp_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ if(!*space)
+ *space = tmp_space;
+
done:
+ /* Free temporary space if not passed to caller (only happens on error) */
+ if(!*space && tmp_space)
+ if(H5S_close(tmp_space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_none_deserialize() */
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index 0a9df69..91f3ed1 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -132,7 +132,7 @@ typedef hssize_t (*H5S_sel_serial_size_func_t)(const H5S_t *space);
/* Method to store current selection in "serialized" form (a byte sequence suitable for storing on disk) */
typedef herr_t (*H5S_sel_serialize_func_t)(const H5S_t *space, uint8_t *buf);
/* Method to store create selection from "serialized" form (a byte sequence suitable for storing on disk) */
-typedef herr_t (*H5S_sel_deserialize_func_t)(H5S_t *space, const uint8_t *buf);
+typedef herr_t (*H5S_sel_deserialize_func_t)(H5S_t **space, const uint8_t **p);
/* Method to determine smallest n-D bounding box containing the current selection */
typedef herr_t (*H5S_sel_bounds_func_t)(const H5S_t *space, hsize_t *start, hsize_t *end);
/* Method to determine linear offset of initial element in selection within dataspace */
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index 70842df..e55834d 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -818,7 +818,7 @@ H5S_point_serial_size (const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_point_serialize (const H5S_t *space, uint8_t *buf)
+H5S_point_serialize (const H5S_t *space, uint8_t **p)
{
H5S_pnt_node_t *curr; /* Point information nodes */
uint8_t *lenp; /* pointer to length location for later storage */
@@ -830,29 +830,29 @@ H5S_point_serialize (const H5S_t *space, uint8_t *buf)
HDassert(space);
/* Store the preamble information */
- UINT32ENCODE(buf, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
- UINT32ENCODE(buf, (uint32_t)1); /* Store the version number */
- UINT32ENCODE(buf, (uint32_t)0); /* Store the un-used padding */
- lenp=buf; /* keep the pointer to the length location for later */
- buf+=4; /* skip over space for length */
+ UINT32ENCODE(*p, (uint32_t)H5S_GET_SELECT_TYPE(space)); /* Store the type of selection */
+ UINT32ENCODE(*p, (uint32_t)1); /* Store the version number */
+ UINT32ENCODE(*p, (uint32_t)0); /* Store the un-used padding */
+ lenp=*p; /* keep the pointer to the length location for later */
+ *p+=4; /* skip over space for length */
/* Encode number of dimensions */
- UINT32ENCODE(buf, (uint32_t)space->extent.rank);
+ UINT32ENCODE(*p, (uint32_t)space->extent.rank);
len+=4;
/* Encode number of elements */
- UINT32ENCODE(buf, (uint32_t)space->select.num_elem);
+ UINT32ENCODE(*p, (uint32_t)space->select.num_elem);
len+=4;
/* Encode each point in selection */
curr=space->select.sel_info.pnt_lst->head;
while(curr!=NULL) {
/* Add 4 bytes times the rank for each element selected */
- len+=4*space->extent.rank;
+ *p+=4*space->extent.rank;
/* Encode each point */
for(u=0; u<space->extent.rank; u++)
- UINT32ENCODE(buf, (uint32_t)curr->pnt[u]);
+ UINT32ENCODE(*p, (uint32_t)curr->pnt[u]);
curr=curr->next;
} /* end while */
@@ -884,8 +884,9 @@ H5S_point_serialize (const H5S_t *space, uint8_t *buf)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_point_deserialize (H5S_t *space, const uint8_t *buf)
+H5S_point_deserialize (H5S_t **space, const uint8_t **p)
{
+ H5S_t *tmp_space;
H5S_seloper_t op=H5S_SELECT_SET; /* Selection operation */
uint32_t rank; /* Rank of points */
size_t num_elem=0; /* Number of elements in selection */
@@ -897,14 +898,29 @@ H5S_point_deserialize (H5S_t *space, const uint8_t *buf)
/* Check args */
HDassert(space);
- HDassert(buf);
+ HDassert(p);
+ HDassert(*p);
/* Deserialize points to select */
- buf += 16; /* Skip over selection header */
- UINT32DECODE(buf, rank); /* decode the rank of the point selection */
- if(rank != space->extent.rank)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace")
- UINT32DECODE(buf, num_elem); /* decode the number of points */
+ *p += 12; /* Skip over remaining selection header */
+ UINT32DECODE(*p, rank); /* decode the rank of the point selection */
+ UINT32DECODE(*p, num_elem); /* decode the number of points */
+
+ /* Allocate space if not provided */
+ if(!*space) {
+ if(NULL == (tmp_space = H5S_create(H5S_SIMPLE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace")
+
+ /* Set rank of dataspace */
+ tmp_space->extent.rank = rank;
+ } /* end if */
+ else {
+ tmp_space = *space;
+
+ /* Verify rank of dataspace */
+ if(rank!=tmp_space->extent.rank)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "rank of pointer does not match dataspace")
+ } /* end else */
/* Allocate space for the coordinates */
if(NULL == (coord = (hsize_t *)H5MM_malloc(num_elem * rank * sizeof(hsize_t))))
@@ -913,13 +929,21 @@ H5S_point_deserialize (H5S_t *space, const uint8_t *buf)
/* Retrieve the coordinates from the buffer */
for(tcoord = coord, i = 0; i < num_elem; i++)
for(j = 0; j < (unsigned)rank; j++, tcoord++)
- UINT32DECODE(buf, *tcoord);
+ UINT32DECODE(*p, *tcoord);
/* Select points */
- if(H5S_select_elements(space, op, num_elem, (const hsize_t *)coord) < 0)
+ if(H5S_select_elements(tmp_space, op, num_elem, (const hsize_t *)coord) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
+ if(!*space)
+ *space = tmp_space;
+
done:
+ /* Free temporary space if not passed to caller (only happens on error) */
+ if(!*space && tmp_space)
+ if(H5S_close(tmp_space) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "can't close dataspace")
+
/* Free the coordinate array if necessary */
if(coord != NULL)
H5MM_xfree(coord);
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 2cb4b38..7d22f08 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -241,7 +241,7 @@ H5S_select_serial_size(const H5S_t *space)
USAGE
herr_t H5S_select_serialize(space, buf)
const H5S_t *space; IN: Dataspace with selection to serialize
- uint8_t *buf; OUT: Buffer to put serialized selection
+ uint8_t **p; OUT: Buffer to put serialized selection
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
@@ -256,7 +256,7 @@ H5S_select_serial_size(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_serialize(const H5S_t *space, uint8_t *buf)
+H5S_select_serialize(const H5S_t *space, uint8_t **p)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -266,7 +266,7 @@ H5S_select_serialize(const H5S_t *space, uint8_t *buf)
HDassert(buf);
/* Call the selection type's serialize function */
- ret_value=(*space->select.type->serialize)(space,buf);
+ ret_value=(*space->select.type->serialize)(space,p);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_select_serialize() */
@@ -444,9 +444,8 @@ H5S_select_valid(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_select_deserialize (H5S_t *space, const uint8_t *buf)
+H5S_select_deserialize (H5S_t **space, const uint8_t **p)
{
- const uint8_t *tbuf; /* Temporary pointer to the selection type */
uint32_t sel_type; /* Pointer to the selection type */
herr_t ret_value=FAIL; /* return value */
@@ -454,23 +453,22 @@ H5S_select_deserialize (H5S_t *space, const uint8_t *buf)
HDassert(space);
- tbuf=buf;
- UINT32DECODE(tbuf, sel_type);
+ UINT32DECODE(*p, sel_type);
switch(sel_type) {
case H5S_SEL_POINTS: /* Sequence of points selected */
- ret_value=(*H5S_sel_point->deserialize)(space,buf);
+ ret_value=(*H5S_sel_point->deserialize)(space,p);
break;
case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
- ret_value=(*H5S_sel_hyper->deserialize)(space,buf);
+ ret_value=(*H5S_sel_hyper->deserialize)(space,p);
break;
case H5S_SEL_ALL: /* Entire extent selected */
- ret_value=(*H5S_sel_all->deserialize)(space,buf);
+ ret_value=(*H5S_sel_all->deserialize)(space,p);
break;
case H5S_SEL_NONE: /* Nothing selected */
- ret_value=(*H5S_sel_none->deserialize)(space,buf);
+ ret_value=(*H5S_sel_none->deserialize)(space,p);
break;
default:
diff --git a/src/Makefile.am b/src/Makefile.am
index 4b55144..6a745e2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -48,7 +48,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5D.c H5Dbtree.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \
H5Ddeprec.c H5Defl.c H5Dfill.c H5Dint.c \
H5Dio.c H5Dlayout.c \
- H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c \
+ H5Dmpio.c H5Doh.c H5Dscatgath.c H5Dselect.c H5Dtest.c H5Dvirtual.c \
H5E.c H5Edeprec.c H5Eint.c \
H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \
H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \