summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2002-03-29 23:46:56 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2002-03-29 23:46:56 (GMT)
commit1c1653aa40acb537d91f37013e5de7ee83e8e052 (patch)
tree2f1f7f3cd1c028ae79265749d890bf1e1d51ba32
parent65d52eaf8e3126d11d8fe2992b12942c01df1776 (diff)
downloadhdf5-1c1653aa40acb537d91f37013e5de7ee83e8e052.zip
hdf5-1c1653aa40acb537d91f37013e5de7ee83e8e052.tar.gz
hdf5-1c1653aa40acb537d91f37013e5de7ee83e8e052.tar.bz2
[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
-rw-r--r--src/H5Odtype.c8
-rw-r--r--src/H5T.c80
-rw-r--r--src/H5Tpkg.h3
-rw-r--r--test/tvlstr.c75
4 files changed, 150 insertions, 16 deletions
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 545531f..ed94cd4 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -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) {
diff --git a/src/H5T.c b/src/H5T.c
index d86aff0..50d67e4 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -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;
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 1ffaa4f..9be4778 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -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 */
diff --git a/test/tvlstr.c b/test/tvlstr.c
index e17b0c8..3c09746 100644
--- a/test/tvlstr.c
+++ b/test/tvlstr.c
@@ -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";
@@ -226,6 +228,75 @@ test_vlstrings_basic(void)
/****************************************************************
**
+** 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.
** Tests writing VL strings as attributes
**
@@ -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();