summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>1999-06-04 22:27:28 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>1999-06-04 22:27:28 (GMT)
commit2a10e682a13244d5c61982445f2d6ec5bc990a36 (patch)
treefd25460dfb65d05ee3b3f19a5b11fe728a0e7adf /src
parentdf96f4362a0872e832cb0b995e209da4e315cb9d (diff)
downloadhdf5-2a10e682a13244d5c61982445f2d6ec5bc990a36.zip
hdf5-2a10e682a13244d5c61982445f2d6ec5bc990a36.tar.gz
hdf5-2a10e682a13244d5c61982445f2d6ec5bc990a36.tar.bz2
[svn-r1305] Checkpointing the VL datatype code. I believe the core functionality is here,
accessed with H5Tvlen_create, but I need to start writing tests now. Also the more esoteric API calls (such as H5Tget_vlen_buf_size and the memory management calls) aren't implemented yet.
Diffstat (limited to 'src')
-rw-r--r--src/H5A.c12
-rw-r--r--src/H5D.c34
-rw-r--r--src/H5Odtype.c87
-rw-r--r--src/H5Shyper.c6
-rw-r--r--src/H5T.c127
-rw-r--r--src/H5TB.c10
-rw-r--r--src/H5TBprivate.h2
-rw-r--r--src/H5Tconv.c208
-rw-r--r--src/H5Tpkg.h37
-rw-r--r--src/H5Tprivate.h13
-rw-r--r--src/H5Tpublic.h19
-rw-r--r--src/H5Tvlen.c365
-rw-r--r--src/Makefile.in2
13 files changed, 856 insertions, 66 deletions
diff --git a/src/H5A.c b/src/H5A.c
index b7bb4c3..275c350 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -242,6 +242,12 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
"memory allocation failed for attribute info");
attr->name=HDstrdup(name);
attr->dt=H5T_copy(type, H5T_COPY_ALL);
+ /* Mark any VL datatypes as being on disk now */
+ if(H5T_get_class(attr->dt)==H5T_VLEN) {
+ if (H5T_vlen_set_loc(attr->dt, ent->file, H5T_VLEN_DISK)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location");
+ }
+ }
attr->ds=H5S_copy(space);
attr->initialized = TRUE; /*for now, set to false later*/
@@ -955,6 +961,12 @@ H5Aget_type(hid_t attr_id)
HRETURN_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL,
"unable to copy datatype");
}
+ /* Mark any VL datatypes as being in memory now */
+ if(H5T_get_class(dst)==H5T_VLEN) {
+ if (H5T_vlen_set_loc(dst, NULL, H5T_VLEN_MEMORY)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location");
+ }
+ }
if (H5T_lock(dst, FALSE)<0) {
H5T_close(dst);
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
diff --git a/src/H5D.c b/src/H5D.c
index 98bfca9..614bda6 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1,13 +1,13 @@
/****************************************************************************
-* NCSA HDF *
-* Software Development Group *
-* National Center for Supercomputing Applications *
-* University of Illinois at Urbana-Champaign *
-* 605 E. Springfield, Champaign IL 61820 *
-* *
-* For conditions of distribution and use, see the accompanying *
-* hdf/COPYING file. *
-* *
+* NCSA HDF *
+* Software Development Group *
+* National Center for Supercomputing Applications *
+* University of Illinois at Urbana-Champaign *
+* 605 E. Springfield, Champaign IL 61820 *
+* *
+* For conditions of distribution and use, see the accompanying *
+* hdf/COPYING file. *
+* *
****************************************************************************/
#ifdef RCSID
@@ -457,6 +457,12 @@ H5Dget_type(hid_t dset_id)
HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
"unable to copy the data type");
}
+ /* Mark any VL datatypes as being in memory now */
+ if(H5T_get_class(copied_type)==H5T_VLEN) {
+ if (H5T_vlen_set_loc(copied_type, NULL, H5T_VLEN_MEMORY)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location");
+ }
+ }
if (H5T_lock (copied_type, FALSE)<0) {
H5T_close (copied_type);
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
@@ -905,7 +911,17 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
+
+ /* Copy datatype for dataset */
new_dset->type = H5T_copy(type, H5T_COPY_ALL);
+
+ /* Mark any VL datatypes as being on disk now */
+ if(H5T_get_class(new_dset->type)==H5T_VLEN) {
+ if (H5T_vlen_set_loc(new_dset->type, f, H5T_VLEN_DISK)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location");
+ }
+ }
+
efl = &(new_dset->create_parms->efl);
/* Total raw data size */
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 5d3ac32..14f2840 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -77,7 +77,7 @@ static intn interface_initialize_g = 0;
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt)
+H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
{
uintn flags, perm_word, version;
intn i, j;
@@ -229,7 +229,7 @@ H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt)
"memory allocation failed");
}
H5F_addr_undef (&(dt->u.compnd.memb[i].type->ent.header));
- if (H5O_dtype_decode_helper(pp, dt->u.compnd.memb[i].type)<0) {
+ if (H5O_dtype_decode_helper(f, pp, dt->u.compnd.memb[i].type)<0) {
for (j=0; j<=i; j++) H5MM_xfree(dt->u.compnd.memb[j].name);
H5MM_xfree(dt->u.compnd.memb);
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL,
@@ -255,7 +255,7 @@ H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt)
"memory allocation failed");
}
H5F_addr_undef(&(dt->parent->ent.header));
- if (H5O_dtype_decode_helper(pp, dt->parent)<0) {
+ if (H5O_dtype_decode_helper(f, pp, dt->parent)<0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL,
"unable to decode parent data type");
}
@@ -288,6 +288,19 @@ H5O_dtype_decode_helper(const uint8_t **pp, H5T_t *dt)
dt->u.atomic.u.r.rtype = (H5R_type_t)(flags & 0x0f);
break;
+ case H5T_VLEN: /* Variable length datatypes... */
+ /* Decode base type of VL information */
+ H5F_addr_undef(&(dt->parent->ent.header));
+ if (H5O_dtype_decode_helper(f, pp, dt->parent)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode VL parent type");
+ }
+
+ /* Mark this type as on disk */
+ if (H5T_vlen_set_loc(dt, f, H5T_VLEN_DISK)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location");
+ }
+ break;
+
default:
if (flags) {
HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
@@ -583,38 +596,44 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
break;
case H5T_ENUM:
- /*
- * Enumeration data types...
- */
- flags = dt->u.enumer.nmembs & 0xffff;
-
- /* Parent type */
- if (H5O_dtype_encode_helper(pp, dt->parent)<0) {
- HRETURN_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL,
- "unable to encode parent data type");
- }
-
- /* Names, each a multiple of eight bytes */
- for (i=0; i<dt->u.enumer.nmembs; i++) {
- HDstrcpy((char*)(*pp), dt->u.enumer.name[i]);
- n = HDstrlen(dt->u.enumer.name[i]);
- for (z=n+1; z%8; z++) (*pp)[z] = '\0';
- *pp += z;
- }
-
- /* Values */
- HDmemcpy(*pp, dt->u.enumer.value,
- dt->u.enumer.nmembs * dt->parent->size);
- *pp += dt->u.enumer.nmembs * dt->parent->size;
- break;
+ /*
+ * Enumeration data types...
+ */
+ flags = dt->u.enumer.nmembs & 0xffff;
+
+ /* Parent type */
+ if (H5O_dtype_encode_helper(pp, dt->parent)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL,
+ "unable to encode parent data type");
+ }
+
+ /* Names, each a multiple of eight bytes */
+ for (i=0; i<dt->u.enumer.nmembs; i++) {
+ HDstrcpy((char*)(*pp), dt->u.enumer.name[i]);
+ n = HDstrlen(dt->u.enumer.name[i]);
+ for (z=n+1; z%8; z++) (*pp)[z] = '\0';
+ *pp += z;
+ }
+
+ /* Values */
+ HDmemcpy(*pp, dt->u.enumer.value, dt->u.enumer.nmembs * dt->parent->size);
+ *pp += dt->u.enumer.nmembs * dt->parent->size;
+ break;
case H5T_REFERENCE:
- flags |= (dt->u.atomic.u.r.rtype & 0x0f);
- break;
-
+ flags |= (dt->u.atomic.u.r.rtype & 0x0f);
+ break;
+
+ case H5T_VLEN: /* Variable length datatypes... */
+ /* Encode base type of VL information */
+ if (H5O_dtype_encode_helper(pp, dt->parent)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "unable to encode VL parent type");
+ }
+ break;
+
default:
- /*nothing */
- break;
+ /*nothing */
+ break;
}
*hdr++ = ((uintn)(dt->type) & 0x0f) | (H5O_DTYPE_VERSION<<4);
@@ -644,7 +663,7 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
function using malloc() and is returned to the caller.
--------------------------------------------------------------------------*/
static void *
-H5O_dtype_decode(H5F_t UNUSED *f, const uint8_t *p,
+H5O_dtype_decode(H5F_t *f, const uint8_t *p,
H5O_shared_t UNUSED *sh)
{
H5T_t *dt = NULL;
@@ -660,7 +679,7 @@ H5O_dtype_decode(H5F_t UNUSED *f, const uint8_t *p,
}
H5F_addr_undef (&(dt->ent.header));
- if (H5O_dtype_decode_helper(&p, dt) < 0) {
+ if (H5O_dtype_decode_helper(f, &p, dt) < 0) {
H5MM_xfree(dt);
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL,
"can't decode type");
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index f686dfc..09c3b77 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -275,8 +275,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
hi_bounds[0][i].bound!=reg[curr_reg].end) {
/* Enlarge array */
- H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)));
- reg=H5TB_buf_ptr(ret_value);
+ H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),&reg);
/* Initialize with new region */
reg[num_reg].start=lo_bounds[0][i].bound+offset[0];
@@ -369,8 +368,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
(int)reg[curr_reg].end);
#endif /* QAK */
/* Enlarge array */
- H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)));
- reg=H5TB_buf_ptr(ret_value);
+ H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),&reg);
/* Initialize with new region */
reg[num_reg].start=node->start[next_dim]+offset[next_dim];
diff --git a/src/H5T.c b/src/H5T.c
index bba0874..d29f968 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -176,7 +176,7 @@ H5T_init_interface(void)
{
H5T_t *dt = NULL;
hid_t fixedpt=-1, floatpt=-1, string=-1, compound=-1, enum_type=-1;
- hid_t bitfield=-1;
+ hid_t vlen_type=-1, bitfield=-1;
herr_t status;
herr_t ret_value=FAIL;
@@ -189,6 +189,10 @@ H5T_init_interface(void)
"unable to initialize interface");
}
+ /* Make certain there aren't too many classes of datatypes defined */
+ /* Only 16 (numbered 0-15) are supported in the current file format */
+ assert(H5T_NCLASSES<16);
+
/*
* Initialize pre-defined native data types from code generated during
* the library configuration by H5detect.
@@ -702,6 +706,7 @@ H5T_init_interface(void)
bitfield = H5T_STD_B8LE;
compound = H5Tcreate(H5T_COMPOUND, 1);
enum_type = H5Tcreate(H5T_ENUM, 1);
+ vlen_type = H5Tvlen_create(H5T_NATIVE_INT);
status = 0;
/*
* Register conversion functions beginning with the most general and
@@ -731,6 +736,9 @@ H5T_init_interface(void)
status |= H5Tregister(H5T_PERS_SOFT, "enum",
enum_type, enum_type,
H5T_conv_enum);
+ status |= H5Tregister(H5T_PERS_SOFT, "vlen",
+ vlen_type, vlen_type,
+ H5T_conv_vlen);
status |= H5Tregister(H5T_PERS_HARD, "u32le_f64le",
H5T_STD_U32LE_g, H5T_IEEE_F64LE_g,
@@ -1053,6 +1061,7 @@ H5T_init_interface(void)
done:
if (compound>=0) H5Tclose(compound);
if (enum_type>=0) H5Tclose(enum_type);
+ if (vlen_type>=0) H5Tclose(vlen_type);
FUNC_LEAVE(ret_value);
}
@@ -1579,11 +1588,40 @@ H5Tget_class(hid_t type_id)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a data type");
}
- FUNC_LEAVE(dt->type);
+ FUNC_LEAVE(H5T_get_class(dt));
}
/*-------------------------------------------------------------------------
+ * Function: H5T_get_class
+ *
+ * Purpose: Returns the data type class identifier for a datatype ptr.
+ *
+ * Return: Success: One of the non-negative data type class
+ * constants.
+ *
+ * Failure: H5T_NO_CLASS (Negative)
+ *
+ * Programmer: Robb Matzke
+ * Monday, December 8, 1997
+ *
+ * Modifications:
+ * Broke out from H5Tget_class - QAK - 6/4/99
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_class_t
+H5T_get_class(const H5T_t *dt)
+{
+ FUNC_ENTER(H5T_get_class, H5T_NO_CLASS);
+
+ assert(dt);
+
+ FUNC_LEAVE(dt->type);
+} /* end H5T_get_class() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Tget_size
*
* Purpose: Determines the total size of a data type in bytes.
@@ -1674,6 +1712,10 @@ H5Tset_size(hid_t type_id, size_t size)
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"operation not allowed after members are defined");
}
+ if (H5T_COMPOUND==dt->type) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "operation not defined for compound data types");
+ }
/* Do the work */
if (H5T_set_size(dt, size)<0) {
@@ -3604,6 +3646,60 @@ H5Tenum_valueof(hid_t type, const char *name, void *value/*out*/)
}
FUNC_LEAVE(SUCCEED);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tvlen_create
+ *
+ * Purpose: Create a new variable-length data type based on the specified
+ * BASE_TYPE.
+ *
+ * Return: Success: ID of new VL data type
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, May 20, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Tvlen_create(hid_t base_id)
+{
+ H5T_t *base = NULL; /*base data type */
+ H5T_t *dt = NULL; /*new VL data type */
+ hid_t ret_value = FAIL; /*return value */
+
+ FUNC_ENTER(H5Tvlen_create, FAIL);
+ H5TRACE1("i","i",base_id);
+
+ /* Check args */
+ if (H5I_DATATYPE!=H5I_get_type(base_id) || NULL==(base=H5I_object(base_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype");
+ }
+
+ /* Build new type */
+ if (NULL==(dt=H5MM_calloc(sizeof(H5T_t)))) {
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ }
+ dt->type = H5T_VLEN;
+ dt->parent = H5T_copy(base, H5T_COPY_ALL);
+
+ /* Set up VL information */
+ if (H5T_vlen_set_loc(dt, NULL, H5T_VLEN_MEMORY)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location");
+ }
+
+ /* Atomize the type */
+ if ((ret_value=H5I_register(H5I_DATATYPE, dt))<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register datatype");
+ }
+
+ FUNC_LEAVE(ret_value);
+}
+
/*-------------------------------------------------------------------------
@@ -4232,6 +4328,11 @@ H5T_create(H5T_class_t type, size_t size)
}
break;
+ case H5T_VLEN: /* Variable length datatype */
+ HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, NULL,
+ "base type required - use H5Tvlen_create()");
+ break;
+
default:
HRETURN_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, NULL,
"unknown data type class");
@@ -4500,13 +4601,17 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
for (i=0; i<new_dt->u.enumer.nmembs; i++) {
s = old_dt->u.enumer.name[i];
new_dt->u.enumer.name[i] = H5MM_xstrdup(s);
- }
-
+ }
+ } else if (H5T_VLEN == new_dt->type) {
+ /* H5T_copy converts any VL type into a memory VL type */
+ if (H5T_vlen_set_loc(new_dt, NULL, H5T_VLEN_MEMORY)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location");
+ }
} else if (H5T_OPAQUE == new_dt->type) {
- /*
+ /*
* Copy the tag name.
*/
- new_dt->u.opaque.tag = HDstrdup(new_dt->u.opaque.tag);
+ new_dt->u.opaque.tag = HDstrdup(new_dt->u.opaque.tag);
}
FUNC_LEAVE(new_dt);
@@ -4743,7 +4848,7 @@ H5T_is_atomic(const H5T_t *dt)
FUNC_ENTER(H5T_is_atomic, FAIL);
assert(dt);
- if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type && H5T_OPAQUE!=dt->type) {
+ if (H5T_COMPOUND!=dt->type && H5T_ENUM!=dt->type && H5T_VLEN!=dt->type && H5T_OPAQUE!=dt->type) {
ret_value = TRUE;
} else {
ret_value = FALSE;
@@ -5853,6 +5958,14 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2)
if (tmp>0) HGOTO_DONE(1);
}
+ } else if (H5T_VLEN==dt1->type) {
+ /* Sort memory VL datatypes before disk datatypes, somewhat arbitrarily */
+ if(dt1->u.vlen.type==H5T_VLEN_MEMORY && dt1->u.vlen.type==H5T_VLEN_DISK) {
+ HGOTO_DONE(-1);
+ }
+ else if(dt1->u.vlen.type==H5T_VLEN_DISK && dt1->u.vlen.type==H5T_VLEN_MEMORY) {
+ HGOTO_DONE(1);
+ }
} else if (H5T_OPAQUE==dt1->type) {
HGOTO_DONE(HDstrcmp(dt1->u.opaque.tag,dt2->u.opaque.tag));
diff --git a/src/H5TB.c b/src/H5TB.c
index 4b6bf25..2b401b1 100644
--- a/src/H5TB.c
+++ b/src/H5TB.c
@@ -349,9 +349,11 @@ done:
PURPOSE
Resize a temp. buffer to a new size
USAGE
- herr_t H5TB_resize_buf(tbid, size)
+ herr_t H5TB_resize_buf(tbid, size, ptr)
hid_t tbid; IN: Temp. buffer ID to resize
hsize_t size; IN: New size of temp. buffer
+ void **ptr; OUT: Pointer to a pointer to set to the buffer
+ address, if not NULL
RETURNS
non-negative on success, negative on failure
DESCRIPTION
@@ -362,7 +364,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5TB_resize_buf(hid_t tbuf_id, hsize_t size)
+H5TB_resize_buf(hid_t tbuf_id, hsize_t size, void **ptr)
{
herr_t ret_value = FAIL;
H5TB_t *tbuf, /* Pointer to temporary buffer */
@@ -430,6 +432,10 @@ H5TB_resize_buf(hid_t tbuf_id, hsize_t size)
} /* end else */
} /* end if */
+ /* Assign the pointer to the buffer, if requested */
+ if(ptr!=NULL)
+ *ptr=tbuf->buf;
+
FUNC_LEAVE(ret_value);
} /* H5TB_resize_buf() */
diff --git a/src/H5TBprivate.h b/src/H5TBprivate.h
index fbdf979..3b2ac39 100644
--- a/src/H5TBprivate.h
+++ b/src/H5TBprivate.h
@@ -19,7 +19,7 @@
/* Functions defined in H5TB.c */
__DLL__ hid_t H5TB_get_buf(hsize_t size, hbool_t resize, void **ptr);
__DLL__ void *H5TB_buf_ptr(hid_t tbid);
-__DLL__ herr_t H5TB_resize_buf(hid_t tbid, hsize_t size);
+__DLL__ herr_t H5TB_resize_buf(hid_t tbid, hsize_t size, void **ptr);
__DLL__ herr_t H5TB_garbage_coll(void);
__DLL__ herr_t H5TB_release_buf(hid_t tbid);
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index fe4e6c3..5a84ad1 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -14,6 +14,7 @@
#include <H5Eprivate.h>
#include <H5MMprivate.h>
#include <H5Tpkg.h>
+#include <H5TBprivate.h>
/* Conversion data for H5T_conv_struct() */
typedef struct H5T_conv_struct_t {
@@ -1383,6 +1384,213 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
/*-------------------------------------------------------------------------
+ * Function: H5T_conv_vlen
+ *
+ * Purpose: Converts between VL data types in memory and on disk.
+ * This is a soft conversion function. The algorithm is basically:
+ *
+ * For every VL struct in the main buffer:
+ * Allocate space for temporary dst VL data (reuse buffer if possible)
+ * Copy VL data from src buffer into dst buffer
+ * Convert VL data into dst representation
+ * Allocate buffer in dst heap
+ * Write dst VL data into dst heap
+ * Store (heap ID or pointer) and length in main dst buffer
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 26, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ void *_buf, void UNUSED *_bkg)
+{
+ H5T_path_t *tpath; /* Type conversion path */
+ hid_t tsrc_id = -1, tdst_id = -1;/*temporary type atoms */
+ H5T_t *src = NULL; /*source data type */
+ H5T_t *dst = NULL; /*destination data type */
+ size_t olap; /*num overlapping elements */
+ uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/
+ uint8_t **dptr; /* Pointer to correct destination pointer */
+ size_t src_delta, dst_delta; /*source & destination stride */
+ hsize_t seq_len; /* The number of elements in the current sequence */
+ size_t src_base_size, dst_base_size; /*source & destination base size */
+ size_t src_size, dst_size; /*source & destination total size in bytes */
+ hid_t conv_buf_id; /* ID for comversion buffer */
+ void *conv_buf_ptr; /* Temporary conversion buffer */
+ hsize_t conv_buf_size; /* Size of conversion buffer in bytes */
+ uint8_t dbuf[64],*dbuf_ptr=dbuf; /*temp destination buffer */
+ intn direction; /*direction of traversal */
+ uintn elmtno;
+
+ FUNC_ENTER (H5T_conv_struct, FAIL);
+
+ switch (cdata->command) {
+ case H5T_CONV_INIT:
+ /*
+ * First, determine if this conversion function applies to the
+ * conversion path SRC_ID-->DST_ID. If not, return failure;
+ * otherwise initialize the `priv' field of `cdata' with information
+ * that remains (almost) constant for this conversion path.
+ */
+ if (H5I_DATATYPE != H5I_get_type(src_id) || NULL == (src = H5I_object(src_id)) ||
+ H5I_DATATYPE != H5I_get_type(dst_id) || NULL == (dst = H5I_object(dst_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+ assert (H5T_VLEN==src->type);
+ assert (H5T_VLEN==dst->type);
+
+#ifdef LATER
+/* QAK - Set up conversion function? */
+ if (H5T_conv_vlen_init (src, dst, cdata)<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to initialize conversion data");
+ }
+#endif /* LATER */
+ break;
+
+ case H5T_CONV_FREE:
+/* QAK - Nothing to do currently */
+ break;
+
+ case H5T_CONV_CONV:
+ /*
+ * Conversion.
+ */
+ if (H5I_DATATYPE != H5I_get_type(src_id) || NULL == (src = H5I_object(src_id)) ||
+ H5I_DATATYPE != H5I_get_type(dst_id) || NULL == (dst = H5I_object(dst_id))) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+
+ /*
+ * Do we process the values from beginning to end or vice versa? Also,
+ * how many of the elements have the source and destination areas
+ * overlapping?
+ */
+ if (src->size==dst->size) {
+ olap = nelmts;
+ sp = dp = (uint8_t*)_buf;
+ direction = 1;
+ } else if (src->size>=dst->size) {
+ olap = ((dst->size)/(src->size-dst->size))+1; /* potentially this uses the destination buffer 1 extra time, but its faster that floating-point calcs */
+ sp = dp = (uint8_t*)_buf;
+ direction = 1;
+ } else {
+ olap = nelmts-(((src->size)/(dst->size-src->size))+1); /* potentially this uses the destination buffer 1 extra time, but its faster that floating-point calcs */
+ sp = (uint8_t*)_buf + (nelmts-1) * src->size;
+ dp = (uint8_t*)_buf + (nelmts-1) * dst->size;
+ direction = -1;
+ }
+
+ /*
+ * Direction & size of buffer traversal.
+ */
+ src_delta = direction * src->size;
+ dst_delta = direction * dst->size;
+
+ /*
+ * If the source and destination buffers overlap then use a
+ * temporary buffer for the destination.
+ */
+ if (direction>0) {
+ dptr = &dbuf_ptr;
+ } else {
+ dptr = &dp;
+ }
+
+ /* Get the size of the base types in src & dst */
+ src_base_size=H5T_get_size(src->parent);
+ dst_base_size=H5T_get_size(dst->parent);
+
+ /* Get initial conversion buffer */
+ conv_buf_size=MAX(src_base_size,dst_base_size);
+ if((conv_buf_id=H5TB_get_buf(conv_buf_size,FALSE,&conv_buf_ptr))==FAIL)
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+
+ /* Set up conversion path for base elements */
+ tpath = H5T_path_find(src->parent, dst->parent, NULL, NULL);
+ if (NULL==(tpath=H5T_path_find(src->parent, dst->parent, NULL, NULL))) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types");
+ } else if (!H5T_IS_NOOP(tpath)) {
+ if ((tsrc_id = H5I_register(H5I_DATATYPE, H5T_copy(src->parent, H5T_COPY_ALL)))<0 ||
+ (tdst_id = H5I_register(H5I_DATATYPE, H5T_copy(dst->parent, H5T_COPY_ALL)))<0) {
+ HRETURN_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
+ }
+ }
+
+ for (elmtno=0; elmtno<nelmts; elmtno++) {
+ s = sp;
+ d = *dptr;
+
+ /* Get length of sequences in bytes */
+ seq_len=(*(src->u.vlen.getlen))(src->u.vlen.f,s);
+ src_size=seq_len*src_base_size;
+ dst_size=seq_len*dst_base_size;
+
+ /* Check if conversion buffer is large enough, resize if necessary */
+ if(conv_buf_size<MAX(src_size,dst_size)) {
+ conv_buf_size=MAX(src_size,dst_size);
+ if(H5TB_resize_buf(conv_buf_id,conv_buf_size,&conv_buf_ptr)<0)
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ } /* end if */
+
+ /* Read in VL sequence */
+ if((*(src->u.vlen.read))(src->u.vlen.f,s,conv_buf_ptr,src_size)<0)
+ HRETURN_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data");
+
+ /* Convert VL sequence */
+ if (H5T_convert(tpath, tsrc_id, tdst_id, seq_len, conv_buf_ptr, NULL)<0)
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed");
+
+ /* Allocate new VL buffer */
+ if((*(dst->u.vlen.alloc))(dst->u.vlen.f,d,seq_len,dst_base_size)<0)
+ HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "allocation failed for VL data");
+
+ /* Write sequence to destination location */
+ if((*(dst->u.vlen.write))(dst->u.vlen.f,d,conv_buf_ptr,dst_size)<0)
+ HRETURN_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "can't write VL data");
+
+ /*
+ * If we had used a temporary buffer for the destination then we
+ * should copy the value to the true destination buffer.
+ */
+ if (d==dbuf) HDmemcpy (dp, d, dst->size);
+ sp += src_delta;
+ dp += dst_delta;
+
+ /* switch destination pointer around when the olap gets to 0 */
+ if(--olap==0) {
+ if(dptr==&dbuf_ptr)
+ dptr=&dp;
+ else
+ dptr=&dbuf_ptr;
+ } /* end if */
+ }
+
+ /* Release the conversion buffer */
+ H5TB_release_buf(conv_buf_id);
+
+ /* Release the temporary datatype IDs used */
+ if (tsrc_id >= 0) H5I_dec_ref(tsrc_id);
+ if (tdst_id >= 0) H5I_dec_ref(tdst_id);
+
+ break;
+
+ default: /* Some other command we don't know about yet.*/
+ HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "unknown conversion command");
+ } /* end switch */
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_conv_i_i
*
* Purpose: Convert one integer type to another. This is the catch-all
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index ac37243..5a8942d 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -85,6 +85,22 @@ typedef struct H5T_enum_t {
char **name; /*array of symbol names */
} H5T_enum_t;
+/* VL function pointers */
+typedef hsize_t (*H5T_vlen_getlenfunc_t)(H5F_t *f, void *vl_addr);
+typedef herr_t (*H5T_vlen_readfunc_t)(H5F_t *f, void *vl_addr, void *buf, size_t len);
+typedef herr_t (*H5T_vlen_allocfunc_t)(H5F_t *f, void *vl_addr, hsize_t seq_len, hsize_t base_size);
+typedef herr_t (*H5T_vlen_writefunc_t)(H5F_t *f, void *vl_addr, void *buf, size_t len);
+
+/* A VL datatype */
+typedef struct H5T_vlen_t {
+ H5T_vlen_type_t type; /* Type of VL data in buffer */
+ H5F_t *f; /* File ID (if VL data is on disk) */
+ H5T_vlen_getlenfunc_t getlen; /* Function to get VL sequence size (in element units, not bytes) */
+ H5T_vlen_readfunc_t read; /* Function to read VL sequence into buffer */
+ H5T_vlen_allocfunc_t alloc; /* Function to allocate space for VL sequence */
+ H5T_vlen_writefunc_t write; /* Function to write VL sequence from buffer */
+} H5T_vlen_t;
+
/* An opaque data type */
typedef struct H5T_opaque_t {
char *tag; /*short type description string */
@@ -106,10 +122,11 @@ struct H5T_t {
size_t size; /*total size of an instance of this type */
struct H5T_t *parent;/*parent type for derived data types */
union {
- H5T_atomic_t atomic; /*an atomic data type */
- H5T_compnd_t compnd; /*a compound data type (struct) */
- H5T_enum_t enumer; /*an enumeration type (enum) */
- H5T_opaque_t opaque; /*an opaque data type */
+ H5T_atomic_t atomic; /*an atomic data type */
+ H5T_compnd_t compnd; /*a compound data type (struct) */
+ H5T_enum_t enumer; /*an enumeration type (enum) */
+ H5T_vlen_t vlen; /*an VL type */
+ H5T_opaque_t opaque; /*an opaque data type */
} u;
};
@@ -171,6 +188,8 @@ __DLL__ herr_t H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *_buf, void *bkg);
__DLL__ herr_t H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *buf, void *bkg);
+__DLL__ herr_t H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
+ size_t nelmts, void *buf, void *bkg);
__DLL__ herr_t H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *_buf, void *bkg);
__DLL__ herr_t H5T_conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
@@ -477,4 +496,14 @@ __DLL__ ssize_t H5T_bit_find(uint8_t *buf, size_t offset, size_t size,
H5T_sdir_t direction, hbool_t value);
__DLL__ htri_t H5T_bit_inc(uint8_t *buf, size_t start, size_t size);
+/* VL functions */
+__DLL__ hsize_t H5T_vlen_mem_getlen(H5F_t *f, void *vl_addr);
+__DLL__ herr_t H5T_vlen_mem_read(H5F_t *f, void *vl_addr, void *_buf, size_t len);
+__DLL__ herr_t H5T_vlen_mem_alloc(H5F_t *f, void *vl_addr, hsize_t seq_len, hsize_t base_size);
+__DLL__ herr_t H5T_vlen_mem_write(H5F_t *f, void *vl_addr, void *_buf, size_t len);
+__DLL__ hsize_t H5T_vlen_disk_getlen(H5F_t *f, void *vl_addr);
+__DLL__ herr_t H5T_vlen_disk_read(H5F_t *f, void *vl_addr, void *_buf, size_t len);
+__DLL__ herr_t H5T_vlen_disk_alloc(H5F_t *f, void *vl_addr, hsize_t seq_len, hsize_t base_size);
+__DLL__ herr_t H5T_vlen_disk_write(H5F_t *f, void *vl_addr, void *_buf, size_t len);
+
#endif
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index f5aed63..3a3da40 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -53,6 +53,16 @@ typedef struct H5T_path_t {
} H5T_path_t;
/*
+ * VL types allowed.
+ */
+typedef enum {
+ H5T_VLEN_BADTYPE = 0, /* invalid VL Type */
+ H5T_VLEN_MEMORY, /* VL datatype stored in memory */
+ H5T_VLEN_DISK, /* VL datatype stored on disk */
+ H5T_VLEN_MAXTYPE /* highest type (Invalid as true type) */
+} H5T_vlen_type_t;
+
+/*
* Is the path the special no-op path? The no-op function can be set by the
* application and there might be more than one no-op path in a
* multi-threaded application if one thread is using the no-op path when some
@@ -71,6 +81,7 @@ __DLL__ H5T_t *H5T_copy(const H5T_t *old_dt, H5T_copy_t method);
__DLL__ herr_t H5T_commit(H5G_entry_t *loc, const char *name, H5T_t *type);
__DLL__ herr_t H5T_lock(H5T_t *dt, hbool_t immutable);
__DLL__ herr_t H5T_close(H5T_t *dt);
+__DLL__ H5T_class_t H5T_get_class(const H5T_t *dt);
__DLL__ size_t H5T_get_size(const H5T_t *dt);
__DLL__ intn H5T_cmp(const H5T_t *dt1, const H5T_t *dt2);
__DLL__ htri_t H5T_is_atomic(const H5T_t *dt);
@@ -94,4 +105,6 @@ __DLL__ char *H5T_enum_nameof(H5T_t *dt, void *value, char *name/*out*/,
size_t size);
__DLL__ herr_t H5T_enum_valueof(H5T_t *dt, const char *name,
void *value/*out*/);
+__DLL__ herr_t H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_type_t loc);
+
#endif
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index 4b76131..db5e2a6 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -23,6 +23,7 @@
#define HOFFSET(S,M) (offsetof(S,M))
/* These are the various classes of data types */
+/* If this goes over 16 types (0-15), the file format will need to change) */
typedef enum H5T_class_t {
H5T_NO_CLASS = -1, /*error */
H5T_INTEGER = 0, /*integer types */
@@ -33,9 +34,10 @@ typedef enum H5T_class_t {
H5T_OPAQUE = 5, /*opaque types */
H5T_COMPOUND = 6, /*compound types */
H5T_REFERENCE = 7, /*reference types */
- H5T_ENUM = 8, /*enumeration types */
+ H5T_ENUM = 8, /*enumeration types */
+ H5T_VLEN = 9, /*Variable-Length types */
- H5T_NCLASSES = 9 /*this must be last */
+ H5T_NCLASSES /*this must be last */
} H5T_class_t;
/* Byte orders */
@@ -148,6 +150,12 @@ typedef enum H5T_pers_t {
H5T_PERS_SOFT = 1 /*soft conversion function */
} H5T_pers_t;
+/* Variable Length Datatype struct */
+typedef struct {
+ size_t len; /* Length of VL data (in base type units) */
+ void *p; /* Pointer to VL data */
+} hvl_t;
+
/* All data type conversion functions are... */
typedef herr_t (*H5T_conv_t) (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *buf, void *bkg);
@@ -209,8 +217,8 @@ __DLLVAR__ hid_t H5T_IEEE_F64LE_g;
#define H5T_STD_B32LE (H5open(), H5T_STD_B32LE_g)
#define H5T_STD_B64BE (H5open(), H5T_STD_B64BE_g)
#define H5T_STD_B64LE (H5open(), H5T_STD_B64LE_g)
-#define H5T_STD_REF_OBJ (H5open(), H5T_STD_REF_OBJ_g)
-#define H5T_STD_REF_DSETREG (H5open(), H5T_STD_REF_DSETREG_g)
+#define H5T_STD_REF_OBJ (H5open(), H5T_STD_REF_OBJ_g)
+#define H5T_STD_REF_DSETREG (H5open(), H5T_STD_REF_DSETREG_g)
__DLLVAR__ hid_t H5T_STD_I8BE_g;
__DLLVAR__ hid_t H5T_STD_I8LE_g;
__DLLVAR__ hid_t H5T_STD_I16BE_g;
@@ -401,6 +409,9 @@ __DLL__ hid_t H5Tenum_nameof(hid_t type, void *value, char *name/*out*/,
__DLL__ hid_t H5Tenum_valueof(hid_t type, const char *name,
void *value/*out*/);
+/* Operations defined on variable-length data types */
+__DLL__ hid_t H5Tvlen_create(hid_t base_id);
+
/* Operations defined on opaque data types */
__DLL__ herr_t H5Tset_tag(hid_t type, const char *tag);
__DLL__ char *H5Tget_tag(hid_t type);
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
new file mode 100644
index 0000000..4530361
--- /dev/null
+++ b/src/H5Tvlen.c
@@ -0,0 +1,365 @@
+/****************************************************************************
+* NCSA HDF *
+* Software Development Group *
+* National Center for Supercomputing Applications *
+* University of Illinois at Urbana-Champaign *
+* 605 E. Springfield, Champaign IL 61820 *
+* *
+* For conditions of distribution and use, see the accompanying *
+* hdf/COPYING file. *
+* *
+****************************************************************************/
+
+#ifdef RCSID
+static char RcsId[] = "@(#)$Revision$";
+#endif
+
+/* $Id$ */
+
+#define H5T_PACKAGE /*suppress error about including H5Tpkg */
+
+#include <H5private.h> /* Generic Functions */
+#include <H5Eprivate.h> /* Errors */
+#include <H5HGprivate.h> /* Global Heaps */
+#include <H5MMprivate.h> /* Memory Allocation */
+#include <H5Tpkg.h> /* Datatypes */
+
+#define PABLO_MASK H5Tvlen_mask
+
+/* Interface initialization */
+static intn interface_initialize_g = 0;
+#define INTERFACE_INIT NULL
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_set_loc
+ *
+ * Purpose: Sets the location of a VL datatype to be either on disk or in memory
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, June 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_type_t loc)
+{
+ FUNC_ENTER (H5T_vlen_set_loc, FAIL);
+
+ /* check parameters */
+ assert(dt);
+ assert(loc>H5T_VLEN_BADTYPE && loc<H5T_VLEN_MAXTYPE);
+
+ switch(loc) {
+ case H5T_VLEN_MEMORY: /* Memory based VL datatype */
+ assert(f==NULL);
+
+ /* Mark this type as being stored in memory */
+ dt->u.vlen.type=H5T_VLEN_MEMORY;
+
+ /* size in memory, disk size is different */
+ dt->size = sizeof(hvl_t);
+
+ /* Set up the function pointers to access the VL information (in memory) */
+ dt->u.vlen.getlen=H5T_vlen_mem_getlen;
+ dt->u.vlen.read=H5T_vlen_mem_read;
+ dt->u.vlen.alloc=H5T_vlen_mem_alloc;
+ dt->u.vlen.write=H5T_vlen_mem_write;
+
+ /* Reset file ID (since this VL is in memory) */
+ dt->u.vlen.f=NULL;
+ break;
+
+ case H5T_VLEN_DISK: /* Disk based VL datatype */
+ assert(f);
+
+ /* Mark this type as being stored on disk */
+ dt->u.vlen.type=H5T_VLEN_DISK;
+
+ /*
+ * Size of element on disk is 4 bytes for the length, plus the size
+ * of an address in this file. Memory size is different
+ */
+ dt->size = H5F_SIZEOF_ADDR(f)+4;
+
+ /* Set up the function pointers to access the VL information (in memory) */
+ dt->u.vlen.getlen=H5T_vlen_disk_getlen;
+ dt->u.vlen.read=H5T_vlen_disk_read;
+ dt->u.vlen.alloc=H5T_vlen_disk_alloc;
+ dt->u.vlen.write=H5T_vlen_disk_write;
+
+ /* Set file ID (since this VL is on disk) */
+ dt->u.vlen.f=f;
+ break;
+
+ default:
+ HRETURN_ERROR (H5E_DATATYPE, H5E_BADRANGE, FAIL, "invalid VL datatype location");
+ } /* end switch */
+
+ FUNC_LEAVE (SUCCEED);
+} /* end H5T_vlen_disk_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_mem_getlen
+ *
+ * Purpose: Retrieves the length of a memory based VL element.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 2, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t H5T_vlen_mem_getlen(H5F_t UNUSED *f, void *vl_addr)
+{
+ hvl_t *vl=(hvl_t *)vl_addr; /* Pointer to the user's hvl_t information */
+ hsize_t ret_value = FAIL; /*return value */
+
+ FUNC_ENTER (H5T_vlen_mem_getlen, FAIL);
+
+ /* check parameters */
+ assert(vl);
+
+ ret_value=vl->len;
+
+ FUNC_LEAVE (ret_value);
+} /* end H5T_vlen_mem_getlen() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_mem_read
+ *
+ * Purpose: "Reads" the memory based VL sequence into a buffer
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 2, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5T_vlen_mem_read(H5F_t UNUSED *f, void *vl_addr, void *buf, size_t len)
+{
+ hvl_t *vl=(hvl_t *)vl_addr; /* Pointer to the user's hvl_t information */
+
+ FUNC_ENTER (H5T_vlen_mem_read, FAIL);
+
+ /* check parameters */
+ assert(vl && vl->p);
+ assert(buf);
+
+ HDmemcpy(buf,vl->p,len);
+
+ FUNC_LEAVE (SUCCEED);
+} /* end H5T_vlen_mem_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_mem_alloc
+ *
+ * Purpose: Allocates a memory based VL sequence
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 2, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5T_vlen_mem_alloc(H5F_t UNUSED *f, void *vl_addr, hsize_t seq_len, hsize_t base_size)
+{
+ hvl_t *vl=(hvl_t *)vl_addr; /* Pointer to the user's hvl_t information */
+
+ FUNC_ENTER (H5T_vlen_mem_alloc, FAIL);
+
+ /* check parameters */
+ assert(vl);
+
+ if(NULL==(vl->p=H5MM_malloc(seq_len*base_size)))
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data");
+ vl->len=seq_len;
+
+ FUNC_LEAVE (SUCCEED);
+} /* end H5T_vlen_mem_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_mem_write
+ *
+ * Purpose: "Writes" the memory based VL sequence from a buffer
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 2, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5T_vlen_mem_write(H5F_t UNUSED *f, void *vl_addr, void *buf, size_t len)
+{
+ hvl_t *vl=(hvl_t *)vl_addr; /* Pointer to the user's hvl_t information */
+
+ FUNC_ENTER (H5T_vlen_mem_write, FAIL);
+
+ /* check parameters */
+ assert(vl && vl->p);
+ assert(buf);
+
+ HDmemcpy(vl->p,buf,len);
+
+ FUNC_LEAVE (SUCCEED);
+} /* end H5T_vlen_mem_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_disk_getlen
+ *
+ * Purpose: Retrieves the length of a memory based VL element.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 2, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t H5T_vlen_disk_getlen(H5F_t UNUSED *f, void *vl_addr)
+{
+ uint8_t *vl=(uint8_t *)vl_addr; /* Pointer to the disk VL information */
+ hsize_t ret_value = FAIL; /*return value */
+
+ FUNC_ENTER (H5T_vlen_disk_getlen, FAIL);
+
+ /* check parameters */
+ assert(vl);
+
+ UINT32DECODE(vl, ret_value);
+
+ FUNC_LEAVE (ret_value);
+} /* end H5T_vlen_disk_getlen() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_disk_read
+ *
+ * Purpose: Reads the disk based VL sequence into a buffer
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 2, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5T_vlen_disk_read(H5F_t *f, void *vl_addr, void *buf, size_t UNUSED len)
+{
+ uint8_t *vl=(uint8_t *)vl_addr; /* Pointer to the user's hvl_t information */
+ H5HG_t hobjid;
+ uint32_t seq_len;
+
+ FUNC_ENTER (H5T_vlen_disk_read, FAIL);
+
+ /* check parameters */
+ assert(vl);
+ assert(buf);
+ assert(f);
+
+ /* Get the length of the sequence */
+ UINT32DECODE(vl, seq_len); /* Not used */
+
+ /* Get the heap information */
+ H5F_addr_decode(f,(const uint8_t **)&vl,&(hobjid.addr));
+ INT32DECODE(vl,hobjid.idx);
+
+ /* Read the VL information from disk */
+ if(H5HG_read(f,&hobjid,buf)==NULL)
+ HRETURN_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "Unable to read VL information");
+
+ FUNC_LEAVE (SUCCEED);
+} /* end H5T_vlen_disk_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_disk_alloc
+ *
+ * Purpose: Allocates a disk based VL sequence
+ * NOTE: This function is currently a NOOP, allocation of the heap block
+ * is done when the block is written out.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 2, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5T_vlen_disk_alloc(H5F_t UNUSED *f, void UNUSED *vl_addr, hsize_t UNUSED seq_len, hsize_t UNUSED base_size)
+{
+ FUNC_ENTER (H5T_vlen_disk_alloc, FAIL);
+
+ /* check parameters */
+
+ FUNC_LEAVE (SUCCEED);
+} /* end H5T_vlen_disk_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_disk_write
+ *
+ * Purpose: Writes the disk based VL sequence from a buffer
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, June 2, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t H5T_vlen_disk_write(H5F_t *f, void *vl_addr, void *buf, size_t len)
+{
+ uint8_t *vl=(uint8_t *)vl_addr; /* Pointer to the user's hvl_t information */
+ H5HG_t hobjid;
+ uint32_t seq_len;
+
+ FUNC_ENTER (H5T_vlen_disk_write, FAIL);
+
+ /* check parameters */
+ assert(vl);
+ assert(buf);
+ assert(f);
+
+ /* Set the length of the sequence */
+ UINT32ENCODE(vl, seq_len);
+
+ /* Write the VL information to disk (allocates space also) */
+ if(H5HG_insert(f,len,buf,&hobjid)<0)
+ HRETURN_ERROR(H5E_DATATYPE, H5E_WRITEERROR, FAIL, "Unable to write VL information");
+
+ /* Get the heap information */
+ H5F_addr_encode(f,&vl,&hobjid.addr);
+ INT32ENCODE(vl,hobjid.idx);
+
+ FUNC_LEAVE (SUCCEED);
+} /* end H5T_vlen_disk_write() */
+
diff --git a/src/Makefile.in b/src/Makefile.in
index 6eb4786..8b8c9bc 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -26,7 +26,7 @@ LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcore.c \
H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c H5Osdspace.c H5Oshared.c \
H5Ostab.c H5P.c H5R.c H5RA.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c \
H5Snone.c H5Spoint.c H5Sselect.c H5T.c H5Tbit.c H5Tconv.c H5Tinit.c \
- H5TB.c H5V.c H5Z.c
+ H5Tvlen.c H5TB.c H5V.c H5Z.c
LIB_OBJ=$(LIB_SRC:.c=.lo)