[svn-r5123]

Purpose:
    Bug fix(#697)
Description:
    Variable-length string wasn't treated as string.
Solution:
    Added character set and padding into VL string type.
Platforms tested:
    FreeBSD
This commit is contained in:
Raymond Lu 2002-03-29 18:46:56 -05:00
parent 65d52eaf8e
commit 1c1653aa40
4 changed files with 150 additions and 16 deletions

View File

@ -352,6 +352,10 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
case H5T_VLEN: /* Variable length datatypes... */
/* Set the type of VL information, either sequence or string */
dt->u.vlen.type = (H5T_vlen_type_t)(flags & 0x0f);
if(dt->u.vlen.type == H5T_VLEN_STRING) {
dt->u.vlen.pad = (H5T_str_t)((flags>>4) & 0x0f);
dt->u.vlen.cset = (H5T_cset_t)((flags>>8) & 0x0f);
} /* end if */
/* Decode base type of VL information */
if (NULL==(dt->parent = H5FL_ALLOC(H5T_t,1)))
@ -730,6 +734,10 @@ H5O_dtype_encode_helper(uint8_t **pp, const H5T_t *dt)
case H5T_VLEN: /* Variable length datatypes... */
flags |= (dt->u.vlen.type & 0x0f);
if(dt->u.vlen.type == H5T_VLEN_STRING) {
flags |= (dt->u.vlen.pad & 0x0f) << 4;
flags |= (dt->u.vlen.cset & 0x0f) << 8;
} /* end if */
/* Encode base type of VL information */
if (H5O_dtype_encode_helper(pp, dt->parent)<0) {

View File

@ -3755,14 +3755,23 @@ H5Tget_cset(hid_t type_id)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_CSET_ERROR,
"not a data type");
}
if (dt->parent) dt = dt->parent; /*defer to parent*/
if (H5T_STRING != dt->type) {
/* Don't see any reason for this. Causes problem for variable-length
* string. -SLU (& QAK) */
/*if (dt->parent) dt = dt->parent;*/ /*defer to parent*/
if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING ==
dt->u.vlen.type))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_CSET_ERROR,
"operation not defined for data type class");
}
/* result */
cset = dt->u.atomic.u.s.cset;
if(H5T_STRING == dt->type)
cset = dt->u.atomic.u.s.cset;
else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type)
cset = dt->u.vlen.cset;
else
HRETURN_ERROR(H5E_DATATYPE, H5E_BADVALUE, H5T_CSET_ERROR,
"can't get cset info");
FUNC_LEAVE(cset);
}
@ -3806,14 +3815,24 @@ H5Tset_cset(hid_t type_id, H5T_cset_t cset)
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
"illegal character set type");
}
if (dt->parent) dt = dt->parent; /*defer to parent*/
if (H5T_STRING != dt->type) {
/* Don't see any reason for this. Causes problem for variable-length
* string. -SLU (& QAK) */
/*if (dt->parent) dt = dt->parent;*/ /*defer to parent*/
if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING ==
dt->u.vlen.type))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"operation not defined for data type class");
}
/* Commit */
dt->u.atomic.u.s.cset = cset;
if(H5T_STRING == dt->type)
dt->u.atomic.u.s.cset = cset;
else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type)
dt->u.vlen.cset = cset;
else
HRETURN_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL,
"can't set cset info");
FUNC_LEAVE(SUCCEED);
}
@ -3853,14 +3872,23 @@ H5Tget_strpad(hid_t type_id)
NULL == (dt = H5I_object(type_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_STR_ERROR, "not a data type");
}
if (dt->parent) dt = dt->parent; /*defer to parent*/
if (H5T_STRING != dt->type) {
/* Don't see any reason for this. Causes problem for variable-length
* string. -SLU (& QAK) */
/* if (dt->parent) dt = dt->parent;*/ /*defer to parent*/
if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING ==
dt->u.vlen.type))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5T_STR_ERROR,
"operation not defined for data type class");
}
/* result */
strpad = dt->u.atomic.u.s.pad;
if(H5T_STRING == dt->type)
strpad = dt->u.atomic.u.s.pad;
else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type)
strpad = dt->u.vlen.pad;
else
HRETURN_ERROR(H5E_DATATYPE, H5E_BADVALUE, H5T_STR_ERROR,
"can't get strpad info");
FUNC_LEAVE(strpad);
}
@ -3914,14 +3942,24 @@ H5Tset_strpad(hid_t type_id, H5T_str_t strpad)
if (strpad < 0 || strpad >= H5T_NSTR) {
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "illegal string pad type");
}
if (dt->parent) dt = dt->parent; /*defer to parent*/
if (H5T_STRING != dt->type) {
/* Don't see any reason for this. Causes problem for variable-length
* string. -SLU (& QAK) */
/* if (dt->parent) dt = dt->parent;*/ /*defer to parent*/
if (!(H5T_STRING == dt->type || (H5T_VLEN == dt->type && H5T_VLEN_STRING ==
dt->u.vlen.type))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"operation not defined for data type class");
}
/* Commit */
dt->u.atomic.u.s.pad = strpad;
if(H5T_STRING == dt->type)
dt->u.atomic.u.s.pad = strpad;
else if(H5T_VLEN == dt->type && H5T_VLEN_STRING == dt->u.vlen.type)
dt->u.vlen.pad = strpad;
else
HRETURN_ERROR(H5E_DATATYPE, H5E_BADVALUE, H5T_STR_ERROR,
"can't set strpad info");
FUNC_LEAVE(SUCCEED);
}
@ -6043,6 +6081,8 @@ H5T_set_size(H5T_t *dt, size_t size)
/* Convert string to variable-length datatype */
if(size==H5T_VARIABLE) {
H5T_t *base = NULL; /* base data type */
H5T_cset_t tmp_cset; /* Temp. cset info */
H5T_str_t tmp_strpad; /* Temp. strpad info */
/* Get a copy of unsigned char type as the base/parent type */
if (NULL==(base=H5I_object(H5T_NATIVE_UCHAR)))
@ -6053,17 +6093,27 @@ H5T_set_size(H5T_t *dt, size_t size)
dt->type = H5T_VLEN;
/*
* Force conversions (i.e. memory to memory conversions should duplicate
* data, not point to the same VL strings)
* Force conversions (i.e. memory to memory conversions
* should duplicate data, not point to the same VL strings)
*/
dt->force_conv = TRUE;
/* Before we mess with the info in the union, extract the
* values we need */
tmp_cset=dt->u.atomic.u.s.cset;
tmp_strpad=dt->u.atomic.u.s.pad;
/* This is a string, not a sequence */
dt->u.vlen.type = H5T_VLEN_STRING;
/* Set character set and padding information */
dt->u.vlen.cset = tmp_cset;
dt->u.vlen.pad = tmp_strpad;
/* Set up VL information */
if (H5T_vlen_mark(dt, NULL, H5T_VLEN_MEMORY)<0)
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location");
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"invalid VL location");
} else {
prec = 8 * size;

View File

@ -98,6 +98,9 @@ typedef herr_t (*H5T_vlen_writefunc_t)(hid_t dxpl_id, H5F_t *f, void *vl_addr, v
typedef struct H5T_vlen_t {
H5T_vlen_type_t type; /* Type of VL data in buffer */
H5T_vlen_loc_t loc; /* Location of VL data in buffer */
H5T_cset_t cset; /* For VL string. character set */
H5T_str_t pad; /* For VL string. space or null padding of
* extra bytes */
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 */

View File

@ -41,6 +41,8 @@
#define SPACE2_DIM1 10
#define SPACE2_DIM2 10
#define VLSTR_TYPE "vl_string_type"
/* String for testing attributes */
static const char *string_att = "This is the string for the attribute";
@ -224,6 +226,75 @@ test_vlstrings_basic(void)
} /* end test_vlstrings_basic() */
/****************************************************************
**
** test_vlstring_type(): Test VL string type.
** Tests if VL string is treated as string.
**
****************************************************************/
static void test_vlstring_type(void)
{
hid_t fid; /* HDF5 File IDs */
hid_t tid_vlstr, str;
H5T_cset_t cset;
H5T_str_t pad;
size_t size;
herr_t ret;
/* Output message about test being performed */
MESSAGE(5, ("Testing VL String type\n"));
/* Create file */
fid = H5Fcreate(DATAFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
CHECK(fid, FAIL, "H5Fcreate");
/* Create a datatype to refer to */
tid_vlstr = H5Tcopy(H5T_C_S1);
CHECK(tid_vlstr, FAIL, "H5Tcopy");
/* Change padding and verify it */
ret = H5Tset_strpad(tid_vlstr, H5T_STR_NULLPAD);
CHECK(ret, FAIL, "H5Tset_strpad");
pad = H5Tget_strpad(tid_vlstr);
VERIFY(pad, H5T_STR_NULLPAD, "H5Tget_strpad");
/* Convert to variable-length string */
ret = H5Tset_size(tid_vlstr, H5T_VARIABLE);
CHECK(ret, FAIL, "H5Tset_size");
/* Check default character set and padding */
cset = H5Tget_cset(tid_vlstr);
VERIFY(cset, H5T_CSET_ASCII, "H5Tget_cset");
pad = H5Tget_strpad(tid_vlstr);
VERIFY(pad, H5T_STR_NULLPAD, "H5Tget_strpad");
/* Commit variable-length string datatype to storage */
ret = H5Tcommit(fid, VLSTR_TYPE, tid_vlstr);
CHECK(ret, FAIL, "H5Tcommit");
/* Close datatype */
ret = H5Tclose(tid_vlstr);
CHECK(ret, FAIL, "H5Tclose");
/* Open the variable-length string datatype just created */
tid_vlstr = H5Topen(fid, VLSTR_TYPE);
CHECK(tid_vlstr, FAIL, "H5Topen");
/* Verify character set and padding */
cset = H5Tget_cset(tid_vlstr);
VERIFY(cset, H5T_CSET_ASCII, "H5Tget_cset");
pad = H5Tget_strpad(tid_vlstr);
VERIFY(pad, H5T_STR_NULLPAD, "H5Tget_strpad");
/* Close datatype and file */
ret = H5Tclose(tid_vlstr);
CHECK(ret, FAIL, "H5Tclose");
ret = H5Fclose(fid);
CHECK(ret, FAIL, "H5Fclose");
} /* end test_vlstring_type() */
/****************************************************************
**
** test_write_vl_string_attribute(): Test basic VL string code.
@ -353,7 +424,9 @@ test_vlstrings(void)
MESSAGE(5, ("Testing Variable-Length Strings\n"));
/* These next tests use the same file */
test_vlstrings_basic(); /* Test basic VL string datatype */
/* Test basic VL string datatype */
test_vlstrings_basic();
test_vlstring_type();
/* Test using VL strings in attributes */
test_write_vl_string_attribute();