From 2a10e682a13244d5c61982445f2d6ec5bc990a36 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Fri, 4 Jun 1999 17:27:28 -0500 Subject: [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. --- src/H5A.c | 12 ++ src/H5D.c | 34 +++-- src/H5Odtype.c | 87 ++++++++----- src/H5Shyper.c | 6 +- src/H5T.c | 127 +++++++++++++++++-- src/H5TB.c | 10 +- src/H5TBprivate.h | 2 +- src/H5Tconv.c | 208 +++++++++++++++++++++++++++++++ src/H5Tpkg.h | 37 +++++- src/H5Tprivate.h | 13 ++ src/H5Tpublic.h | 19 ++- src/H5Tvlen.c | 365 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Makefile.in | 2 +- 13 files changed, 856 insertions(+), 66 deletions(-) create mode 100644 src/H5Tvlen.c 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; iu.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; iu.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)),®); /* 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)),®); /* 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; iu.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 #include #include +#include /* 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; elmtnou.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_sizeu.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 /* Generic Functions */ +#include /* Errors */ +#include /* Global Heaps */ +#include /* Memory Allocation */ +#include /* 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 && locu.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) -- cgit v0.12