summaryrefslogtreecommitdiffstats
path: root/src
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 /src
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
Diffstat (limited to 'src')
-rw-r--r--src/H5Odtype.c8
-rw-r--r--src/H5T.c80
-rw-r--r--src/H5Tpkg.h3
3 files changed, 76 insertions, 15 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 */