summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/snapshot42
-rw-r--r--doc/html/Datatypes.html36
-rw-r--r--doc/html/H5.format.html87
-rw-r--r--src/.distdep98
-rw-r--r--src/H5.c17
-rw-r--r--src/H5Odtype.c10
-rw-r--r--src/H5T.c49
-rw-r--r--src/H5Tconv.c228
-rw-r--r--src/H5Tpkg.h2
-rw-r--r--src/H5Tpublic.h49
-rw-r--r--test/.distdep96
-rw-r--r--test/chunk.c64
-rw-r--r--test/dtypes.c339
13 files changed, 901 insertions, 216 deletions
diff --git a/bin/snapshot b/bin/snapshot
index 31a7fa3..1d9c13f 100755
--- a/bin/snapshot
+++ b/bin/snapshot
@@ -32,24 +32,44 @@ if [ -z "$CVSROOT" ]; then
fi
cvs -Q co -d ${COMPARE}/current hdf5 || exit 1
-# Compare it with the previous version.
+# Compare it with the previous version. Compare only files listed in
+# the MANIFEST plus the MANIFEST itself.
if [ -d ${COMPARE}/previous ]; then
- if (diff -r -I H5_VERS_RELEASE -I " released on " --exclude CVS \
- ${COMPARE}/previous ${COMPARE}/current); then
- update=no
+ if (diff ${COMPARE}/{previous,current}/MANIFEST); then
+ for src in `cat ${COMPARE}/current/MANIFEST`; do
+ if (diff -I H5_VERS_RELEASE -I " released on " \
+ ${COMPARE}/{previous,current}/$src); then
+ snapshot=no
+ else
+ snapshot=yes
+ break
+ fi
+ done
else
- update=yes
+ snapshot=yes
fi
else
- update=yes
+ snapshot=yes
+fi
+
+# Make sure all the serial tests work.
+if [ "$snapshot" = "yes" ]; then
+ if (cd ${COMPARE}/current; make _test); then
+ :
+ else
+ snapshot=no
+ fi
+ (cd ${COMPARE}/current; make distclean)
fi
# Release snapshot, update version, and commit to cvs
-if [ "$update" = "yes" ]; then
- (cd ${COMPARE}/current; \
- ./bin/release -d $ARCHIVES $METHODS; \
- ./bin/h5vers -i; \
- cvs -Q commit -m Snapshot )
+if [ "$snapshot" = "yes" ]; then
+ (
+ cd ${COMPARE}/current
+ ./bin/release -d $ARCHIVES $METHODS
+ ./bin/h5vers -i
+ cvs -Q commit -m Snapshot
+ )
fi
# Replace the previous version with the current version.
diff --git a/doc/html/Datatypes.html b/doc/html/Datatypes.html
index 75bc57e..50e0ab7 100644
--- a/doc/html/Datatypes.html
+++ b/doc/html/Datatypes.html
@@ -159,8 +159,8 @@
type may fail if the precesion must be decremented and the
data type is of the <code>H5T_OPAQUE</code> class or the
<code>H5T_FLOAT</code> bit fields would extend beyond the
- significant part of the type. Increasing the size of an
- <code>H5T_STRING</code> automatically increases the precision
+ significant part of the type. Adjusting the size of an
+ <code>H5T_STRING</code> automatically adjusts the precision
as well. On error, <code>H5Tget_size()</code> returns zero
which is never a valid size.
@@ -388,9 +388,33 @@
programming language: C usually null terminates strings while
Fortran left-justifies and space-pads strings. This property
defines the storage mechanism and can be
- <code>H5T_STR_NULL</code> for C-style strings or
- <code>H5T_STR_SPACE</code> for Fortran-style
- strings. <code>H5Tget_strpad()</code> returns
+
+ <p>
+ <dl>
+ <dt><code>H5T_STR_NULLTERM</code>
+ <dd>A C-style string which is guaranteed to be null
+ terminated. When converting from a longer string the
+ value will be truncated and then a null character
+ appended.
+
+ <br><br>
+ <dt><code>H5T_STR_NULLPAD</code>
+ <dd>A C-style string which is padded with null characters
+ but not necessarily null terminated. Conversion from a
+ long string to a shorter <code>H5T_STR_NULLPAD</code>
+ string will truncate but not null terminate. Conversion
+ from a short value to a longer value will append null
+ characters as with <code>H5T_STR_NULLTERM</code>.
+
+ <br><br>
+ <dt><code>H5T_STR_SPACEPAD</code>
+ <dd>A Fortran-style string which is padded with space
+ characters. This is the same as
+ <code>H5T_STR_NULLPAD</code> except the padding character
+ is a space instead of a null.
+ </dl>
+
+ <p><code>H5Tget_strpad()</code> returns
<code>H5T_STR_ERROR</code> on failure, a negative value (all
successful return values are non-negative).
</dl>
@@ -1364,7 +1388,7 @@ H5Tregister_soft ("cus2be", H5T_INTEGER, H5T_INTEGER, cray_ushort2be);
<address><a href="mailto:koziol@ncsa.uiuc.edu">Quincey Koziol</a></address>
<!-- Created: Thu Dec 4 14:57:32 EST 1997 -->
<!-- hhmts start -->
-Last modified: Thu Jun 18 13:59:12 EDT 1998
+Last modified: Fri Aug 7 10:24:52 EDT 1998
<!-- hhmts end -->
</body>
</html>
diff --git a/doc/html/H5.format.html b/doc/html/H5.format.html
index fff60db..86d591c 100644
--- a/doc/html/H5.format.html
+++ b/doc/html/H5.format.html
@@ -1978,13 +1978,13 @@
<th width="90%">Meaning</th>
</tr>
- <tr>
+ <tr valign=top>
<td>0</td>
<td><b>Byte Order.</b> If zero, byte order is little-endian;
otherwise, byte order is big endian.</td>
</tr>
- <tr>
+ <tr valign=top>
<td>1, 2</td>
<td><b>Padding type.</b> Bit 1 is the lo_pad type and bit 2
is the hi_pad type. If a datum has unused bits at either
@@ -1992,13 +1992,13 @@
locations.</td>
</tr>
- <tr>
+ <tr valign=top>
<td>3</td>
<td><b>Signed.</b> If this bit is set then the fixed-point
number is in 2's complement form.</td>
</tr>
- <tr>
+ <tr valign=top>
<td>4-23</td>
<td>Reserved (zero).</td>
</tr>
@@ -2038,13 +2038,13 @@
<th width="90%">Meaning</th>
</tr>
- <tr>
+ <tr valign=top>
<td>0</td>
<td><b>Byte Order.</b> If zero, byte order is little-endian;
otherwise, byte order is big endian.</td>
</tr>
- <tr>
+ <tr valign=top>
<td>1, 2, 3</td>
<td><b>Padding type.</b> Bit 1 is the low bits pad type, bit 2
is the high bits pad type, and bit 3 is the internal bits
@@ -2053,7 +2053,7 @@
1, 2, or 3 is copied to those locations.</td>
</tr>
- <tr>
+ <tr valign=top>
<td>4-5</td>
<td><b>Normalization.</b> The value can be 0 if there is no
normalization, 1 if the most significant bit of the
@@ -2063,18 +2063,18 @@
appear in this field.</td>
</tr>
- <tr>
+ <tr valign=top>
<td>6-7</td>
<td>Reserved (zero).</td>
</tr>
- <tr>
+ <tr valign=top>
<td>8-15</td>
<td><b>Sign.</b> This is the bit position of the sign
bit.</td>
</tr>
- <tr>
+ <tr valign=top>
<td>16-23</td>
<td>Reserved (zero).</td>
</tr>
@@ -2114,6 +2114,67 @@
</table>
</center>
+ <p>
+ <center>
+ <table border cellpadding=4 width="80%">
+ <caption align=top>
+ <b>Bit Field for Strings (Class 3)</b>
+ </caption>
+
+ <tr align=center>
+ <th width="10%">Bits</th>
+ <th width="90%">Meaning</th>
+ </tr>
+
+ <tr valign=top>
+ <td>0-3</td>
+ <td><b>Padding type.</b> This four-bit value determines the
+ type of padding to use for the string. The values are:
+
+ <dl>
+ <dt><code>0</code> Null terminate.
+ <dd>A zero byte marks the end of the string and is
+ guaranteed to be present after converting a long
+ string to a short string. When converting a short
+ string to a long string the value is padded with
+ additional null characters as necessary.
+
+ <br><br>
+ <dt><code>1</code> Null pad.
+ <dd>Null characters are added to the end of the value
+ during conversions from short values to long values
+ but conversion in the opposite direction simply
+ truncates the value.
+
+ <br><br>
+ <dt><code>2</code> Space pad.
+ <dd>Space characters are added to the end of the value
+ during conversions from short values to long values
+ but conversion in the opposite direction simply
+ truncates the value. This is the Fortran
+ representation of the string.
+
+ <br><br>
+ <dt><code>3-15</code> Reserved.
+ <dd>These values are reserved for future use.
+ </dl>
+ </tr>
+
+ <tr valign=top>
+ <td>4-7</td>
+ <td><b>Character Set.</b> The character set to use for
+ encoding the string. The only character set supported is
+ the 8-bit ASCII (zero) so no translations have been defined
+ yet.</td>
+ </tr>
+
+ <tr valign=top>
+ <td>8-23</td>
+ <td>Reserved (zero).</td>
+ </tr>
+ </table>
+ </center>
+
<p>
<center>
<table border cellpadding=4 width="80%">
@@ -2126,7 +2187,7 @@
<th width="90%">Meaning</th>
</tr>
- <tr>
+ <tr valign=top>
<td>0-15</td>
<td><b>Number of Members.</b> This field contains the number
of members defined for the compound data type. The member
@@ -2134,7 +2195,7 @@
type message.
</tr>
- <tr>
+ <tr valign=top>
<td>15-23</td>
<td>Reserved (zero).</td>
</tr>
@@ -3292,7 +3353,7 @@ data-type.
<address><a href="mailto:koziol@ncsa.uiuc.edu">Quincey Koziol</a></address>
<address><a href="mailto:matzke@llnl.gov">Robb Matzke</a></address>
<!-- hhmts start -->
-Last modified: Tue Aug 4 10:04:40 EDT 1998
+Last modified: Fri Aug 7 11:04:44 EDT 1998
<!-- hhmts end -->
</body>
</html>
diff --git a/src/.distdep b/src/.distdep
index 499fcc6..917a475 100644
--- a/src/.distdep
+++ b/src/.distdep
@@ -341,29 +341,6 @@ H5Ocont.o: \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h
-H5Odtype.o: \
- H5Odtype.c \
- H5private.h \
- H5public.h \
- H5config.h \
- H5Eprivate.h \
- H5Epublic.h \
- H5Ipublic.h \
- H5Gprivate.h \
- H5Gpublic.h \
- H5Bprivate.h \
- H5Bpublic.h \
- H5Fprivate.h \
- H5Fpublic.h \
- H5Dpublic.h \
- H5MMprivate.h \
- H5MMpublic.h \
- H5Oprivate.h \
- H5Opublic.h \
- H5HGprivate.h \
- H5HGpublic.h \
- H5Tprivate.h \
- H5Tpublic.h
H5Olayout.o: \
H5Olayout.c \
H5private.h \
@@ -630,29 +607,6 @@ H5Tbit.o: \
H5Tprivate.h \
H5Tpublic.h \
H5Gprivate.h
-H5Tconv.o: \
- H5Tconv.c \
- H5Iprivate.h \
- H5Ipublic.h \
- H5public.h \
- H5config.h \
- H5private.h \
- H5Eprivate.h \
- H5Epublic.h \
- H5MMprivate.h \
- H5MMpublic.h \
- H5Tpkg.h \
- H5HGprivate.h \
- H5HGpublic.h \
- H5Fprivate.h \
- H5Fpublic.h \
- H5Dpublic.h \
- H5Tprivate.h \
- H5Tpublic.h \
- H5Gprivate.h \
- H5Gpublic.h \
- H5Bprivate.h \
- H5Bpublic.h
H5Tinit.o: \
H5Tinit.c \
H5private.h \
@@ -979,6 +933,19 @@ H5S.o: \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h
+H5Flow.o: \
+ H5Flow.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Ipublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5Dpublic.h \
+ H5MMprivate.h \
+ H5MMpublic.h
H5.o: \
H5.c \
H5private.h \
@@ -1076,19 +1043,29 @@ H5F.o: \
H5Epublic.h \
H5MMprivate.h \
H5MMpublic.h
-H5Flow.o: \
- H5Flow.c \
+H5Odtype.o: \
+ H5Odtype.c \
H5private.h \
H5public.h \
H5config.h \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5MMprivate.h \
- H5MMpublic.h
+ H5MMpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h
H5T.o: \
H5T.c \
H5private.h \
@@ -1117,3 +1094,26 @@ H5T.o: \
H5Eprivate.h \
H5Epublic.h \
H5MMprivate.h
+H5Tconv.o: \
+ H5Tconv.c \
+ H5Iprivate.h \
+ H5Ipublic.h \
+ H5public.h \
+ H5config.h \
+ H5private.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5MMprivate.h \
+ H5MMpublic.h \
+ H5Tpkg.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5Dpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h
diff --git a/src/H5.c b/src/H5.c
index 94291c0..b035ab3 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -1987,19 +1987,22 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...)
fprintf(out, "NULL");
}
} else {
- H5T_str_t str = va_arg (ap, H5T_str_t);
+ H5T_str_t str = va_arg(ap, H5T_str_t);
switch (str) {
case H5T_STR_ERROR:
- fprintf (out, "H5T_STR_ERROR");
+ fprintf(out, "H5T_STR_ERROR");
break;
- case H5T_STR_NULL:
- fprintf (out, "H5T_STR_NULL");
+ case H5T_STR_NULLTERM:
+ fprintf(out, "H5T_STR_NULLTERM");
break;
- case H5T_STR_SPACE:
- fprintf (out, "H5T_STR_SPACE");
+ case H5T_STR_NULLPAD:
+ fprintf(out, "H5T_STR_NULLPAD");
+ break;
+ case H5T_STR_SPACEPAD:
+ fprintf(out, "H5T_STR_SPACEPAD");
break;
default:
- fprintf (out, "%ld", (long)str);
+ fprintf(out, "%ld", (long)str);
break;
}
}
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 8e44223..d4a4d6f 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -122,8 +122,9 @@ H5O_dtype_decode_helper(const uint8 **pp, H5T_t *dt)
dt->u.atomic.offset = 0;
dt->u.atomic.lsb_pad = H5T_PAD_ZERO;
dt->u.atomic.msb_pad = H5T_PAD_ZERO;
- dt->u.atomic.u.s.cset = H5T_CSET_ASCII;
- dt->u.atomic.u.s.pad = H5T_STR_NULL;
+
+ dt->u.atomic.u.s.pad = flags & 0x0f;
+ dt->u.atomic.u.s.cset = (flags>>4) & 0x0f;
break;
case H5T_FLOAT:
@@ -327,8 +328,9 @@ H5O_dtype_encode_helper(uint8 **pp, const H5T_t *dt)
assert (dt->u.atomic.offset == 0);
assert (dt->u.atomic.lsb_pad == H5T_PAD_ZERO);
assert (dt->u.atomic.msb_pad == H5T_PAD_ZERO);
- assert (dt->u.atomic.u.s.cset == H5T_CSET_ASCII);
- assert (dt->u.atomic.u.s.pad == H5T_STR_NULL);
+
+ flags |= (dt->u.atomic.u.s.pad & 0x0f);
+ flags |= (dt->u.atomic.u.s.cset & 0x0f) << 4;
break;
case H5T_FLOAT:
diff --git a/src/H5T.c b/src/H5T.c
index 78b6b51..ca7e571 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -534,7 +534,7 @@ H5T_init_interface(void)
dt->u.atomic.lsb_pad = H5T_PAD_ZERO;
dt->u.atomic.msb_pad = H5T_PAD_ZERO;
dt->u.atomic.u.s.cset = H5T_CSET_ASCII;
- dt->u.atomic.u.s.pad = H5T_STR_NULL;
+ dt->u.atomic.u.s.pad = H5T_STR_NULLTERM;
if ((H5T_C_S1_g = H5I_register(H5_DATATYPE, dt)) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"can't initialize H5T layer");
@@ -560,7 +560,7 @@ H5T_init_interface(void)
dt->u.atomic.lsb_pad = H5T_PAD_ZERO;
dt->u.atomic.msb_pad = H5T_PAD_ZERO;
dt->u.atomic.u.s.cset = H5T_CSET_ASCII;
- dt->u.atomic.u.s.pad = H5T_STR_SPACE;
+ dt->u.atomic.u.s.pad = H5T_STR_SPACEPAD;
if ((H5T_FORTRAN_S1_g = H5I_register(H5_DATATYPE, dt)) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"can't initialize H5T layer");
@@ -570,22 +570,23 @@ H5T_init_interface(void)
* Register conversion functions beginning with the most general and
* ending with the most specific.
*/
- if (H5Tregister_soft ("i_i", H5T_INTEGER, H5T_INTEGER,
- H5T_conv_i_i) < 0) {
+ if (H5Tregister_soft ("i_i", H5T_INTEGER, H5T_INTEGER, H5T_conv_i_i)<0) {
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to register conversion function");
}
- if (H5Tregister_soft ("f_f", H5T_FLOAT, H5T_FLOAT,
- H5T_conv_f_f) < 0) {
+ if (H5Tregister_soft ("f_f", H5T_FLOAT, H5T_FLOAT, H5T_conv_f_f)<0) {
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to register conversion function");
}
- if (H5Tregister_soft("ibo", H5T_INTEGER, H5T_INTEGER,
- H5T_conv_order) < 0) {
+ if (H5Tregister_soft("s_s", H5T_STRING, H5T_STRING, H5T_conv_s_s)<0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to register conversion function");
}
- if (H5Tregister_soft("fbo", H5T_FLOAT, H5T_FLOAT, H5T_conv_order) < 0) {
+ if (H5Tregister_soft("ibo", H5T_INTEGER, H5T_INTEGER, H5T_conv_order)<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to register conversion function");
+ }
+ if (H5Tregister_soft("fbo", H5T_FLOAT, H5T_FLOAT, H5T_conv_order)<0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to register conversion function");
}
@@ -1503,8 +1504,7 @@ H5Tget_precision (hid_t type_id)
* and then the size is increased to insure that significant
* bits do not "hang over" the edge of the data type.
*
- * Changing the precision of an H5T_STRING automatically changes
- * the size as well. The precision must be a multiple of 8.
+ * The precision property of strings is read-only.
*
* When decreasing the precision of a floating point type, set
* the locations and sizes of the sign, mantissa, and exponent
@@ -1564,13 +1564,8 @@ H5Tset_precision (hid_t type_id, size_t prec)
break;
case H5T_STRING:
- if (prec % 8) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
- "precision for this type must be a multiple of 8");
- }
- offset = 0;
- size = prec / 8;
- break;
+ HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL,
+ "precision for this type is read-only");
case H5T_FLOAT:
/*
@@ -2424,6 +2419,16 @@ H5Tget_strpad (hid_t type_id)
* Fortran left-justifies and space-pads strings. This property
* defines the storage mechanism for the string.
*
+ * When converting from a long string to a short string if the
+ * short string is H5T_STR_NULLPAD or H5T_STR_SPACEPAD then the
+ * string is simply truncated; otherwise if the short string is
+ * H5T_STR_NULLTERM it will be truncated and a null terminator
+ * is appended.
+ *
+ * When converting from a short string to a long string, the
+ * long string is padded on the end by appending nulls or
+ * spaces.
+ *
* Return: Success: SUCCEED
*
* Failure: FAIL
@@ -4245,17 +4250,17 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2)
break;
case H5T_STRING:
- if (dt1->u.atomic.u.s.cset < dt1->u.atomic.u.s.cset) {
+ if (dt1->u.atomic.u.s.cset < dt2->u.atomic.u.s.cset) {
HGOTO_DONE(-1);
}
- if (dt1->u.atomic.u.s.cset > dt1->u.atomic.u.s.cset) {
+ if (dt1->u.atomic.u.s.cset > dt2->u.atomic.u.s.cset) {
HGOTO_DONE(1);
}
- if (dt1->u.atomic.u.s.pad < dt1->u.atomic.u.s.pad) {
+ if (dt1->u.atomic.u.s.pad < dt2->u.atomic.u.s.pad) {
HGOTO_DONE(-1);
}
- if (dt1->u.atomic.u.s.pad > dt1->u.atomic.u.s.pad) {
+ if (dt1->u.atomic.u.s.pad > dt2->u.atomic.u.s.pad) {
HGOTO_DONE(1);
}
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index c940474..ce0df3e 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -1321,6 +1321,234 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
/*-------------------------------------------------------------------------
+ * Function: H5T_conv_s_s
+ *
+ * Purpose: Convert one fixed-length string type to another.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Friday, August 7, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
+ void *buf, void __unused__ *bkg)
+{
+ H5T_t *src=NULL; /*source data type */
+ H5T_t *dst=NULL; /*destination data type */
+ intn direction; /*direction of traversal */
+ size_t elmtno; /*element number */
+ size_t olap; /*num overlapping elements */
+ size_t nchars; /*number of characters copied */
+ uint8 *s, *sp, *d, *dp; /*src and dst traversal pointers*/
+ uint8 *dbuf=NULL; /*temp buf for overlap convers. */
+ herr_t ret_value=FAIL; /*return value */
+
+ FUNC_ENTER(H5T_conv_s_s, FAIL);
+
+ switch (cdata->command) {
+ case H5T_CONV_INIT:
+ if (H5_DATATYPE!=H5I_group(src_id) ||
+ NULL==(src=H5I_object(src_id)) ||
+ H5_DATATYPE!=H5I_group(dst_id) ||
+ NULL==(dst=H5I_object(dst_id))) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+ if (8*src->size != src->u.atomic.prec ||
+ 8*dst->size != dst->u.atomic.prec) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision");
+ }
+ if (0 != src->u.atomic.offset ||
+ 0 != dst->u.atomic.offset) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad offset");
+ }
+ if (H5T_CSET_ASCII != src->u.atomic.u.s.cset ||
+ H5T_CSET_ASCII != dst->u.atomic.u.s.cset) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character set");
+ }
+ if (src->u.atomic.u.s.pad<0 || src->u.atomic.u.s.pad>=H5T_NPAD ||
+ dst->u.atomic.u.s.pad<0 || dst->u.atomic.u.s.pad>=H5T_NPAD) {
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character padding");
+ }
+ cdata->need_bkg = H5T_BKG_NO;
+ break;
+
+ case H5T_CONV_FREE:
+ break;
+
+ case H5T_CONV_CONV:
+ /* Get the data types */
+ if (H5_DATATYPE!=H5I_group(src_id) ||
+ NULL==(src=H5I_object(src_id)) ||
+ H5_DATATYPE!=H5I_group(dst_id) ||
+ NULL==(dst=H5I_object(dst_id))) {
+ HGOTO_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) {
+ /*
+ * When the source and destination are the same size we can do
+ * all the conversions in place.
+ */
+ sp = dp = (uint8*)buf;
+ direction = 1;
+ olap = 0;
+ } else if (src->size>=dst->size) {
+ sp = dp = (uint8*)buf;
+ direction = 1;
+ olap = (size_t)(ceil((double)(src->size)/
+ (double)(src->size-dst->size))-1);
+ } else {
+ sp = (uint8*)buf + (nelmts-1) * src->size;
+ dp = (uint8*)buf + (nelmts-1) * dst->size;
+ direction = -1;
+ olap = (size_t)(ceil((double)(dst->size)/
+ (double)(dst->size-src->size))-1);
+ }
+
+ /* Allocate the overlap buffer */
+ if (NULL==(dbuf=H5MM_malloc(dst->size))) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed for string conversion");
+ }
+
+ /* The conversion loop. */
+ for (elmtno=0; elmtno<nelmts; elmtno++) {
+
+ /*
+ * If the source and destination buffers overlap then use a
+ * temporary buffer fot eh destination.
+ */
+ if (direction>0) {
+ s = sp;
+ d = elmtno<olap ? dbuf : dp;
+ } else {
+ s = sp;
+ d = elmtno >= nelmts-olap ? dbuf : dp;
+ }
+#ifndef NDEBUG
+ /* I don't quite trust the overlap calculations yet --rpm */
+ if (src->size==dst->size) {
+ assert(s==d);
+ } else if (d==dbuf) {
+ assert((dp>=sp && dp<sp+src->size) ||
+ (sp>=dp && sp<dp+dst->size));
+ } else {
+ assert((dp<sp && dp+dst->size<=sp) ||
+ (sp<dp && sp+src->size<=dp));
+ }
+#endif
+
+ /* Copy characters from source to destination */
+ switch (src->u.atomic.u.s.pad) {
+ case H5T_STR_NULLTERM:
+ for (nchars=0;
+ nchars<dst->size && nchars<src->size && s[nchars];
+ nchars++) {
+ d[nchars] = s[nchars];
+ }
+ break;
+
+ case H5T_STR_NULLPAD:
+ for (nchars=0;
+ nchars<dst->size && nchars<src->size && s[nchars];
+ nchars++) {
+ d[nchars] = s[nchars];
+ }
+ break;
+
+ case H5T_STR_SPACEPAD:
+ nchars = src->size;
+ while (nchars>0 && ' '==s[nchars-1]) --nchars;
+ nchars = MIN(dst->size, nchars);
+ memcpy(d, s, nchars);
+ break;
+
+ case H5T_STR_RESERVED_3:
+ case H5T_STR_RESERVED_4:
+ case H5T_STR_RESERVED_5:
+ case H5T_STR_RESERVED_6:
+ case H5T_STR_RESERVED_7:
+ case H5T_STR_RESERVED_8:
+ case H5T_STR_RESERVED_9:
+ case H5T_STR_RESERVED_10:
+ case H5T_STR_RESERVED_11:
+ case H5T_STR_RESERVED_12:
+ case H5T_STR_RESERVED_13:
+ case H5T_STR_RESERVED_14:
+ case H5T_STR_RESERVED_15:
+ case H5T_STR_ERROR:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "source string padding method not supported");
+ }
+
+ /* Terminate or pad the destination */
+ switch (dst->u.atomic.u.s.pad) {
+ case H5T_STR_NULLTERM:
+ while (nchars<dst->size) d[nchars++] = '\0';
+ d[dst->size-1] = '\0';
+ break;
+
+ case H5T_STR_NULLPAD:
+ while (nchars<dst->size) d[nchars++] = '\0';
+ break;
+
+ case H5T_STR_SPACEPAD:
+ while (nchars<dst->size) d[nchars++] = ' ';
+ break;
+
+ case H5T_STR_RESERVED_3:
+ case H5T_STR_RESERVED_4:
+ case H5T_STR_RESERVED_5:
+ case H5T_STR_RESERVED_6:
+ case H5T_STR_RESERVED_7:
+ case H5T_STR_RESERVED_8:
+ case H5T_STR_RESERVED_9:
+ case H5T_STR_RESERVED_10:
+ case H5T_STR_RESERVED_11:
+ case H5T_STR_RESERVED_12:
+ case H5T_STR_RESERVED_13:
+ case H5T_STR_RESERVED_14:
+ case H5T_STR_RESERVED_15:
+ case H5T_STR_ERROR:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "destination string padding method not supported");
+ }
+
+ /*
+ * If we 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 += direction * src->size;
+ dp += direction * dst->size;
+ }
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "unknown converson command");
+ }
+ ret_value = SUCCEED;
+
+ done:
+ H5MM_xfree(dbuf);
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_conv_float_double
*
* Purpose: Convert native `float' to native `double' using hardware.
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 05c36a4..8068069 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -133,6 +133,8 @@ herr_t H5T_conv_i_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *_buf, void __unused__ *bkg);
herr_t H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *_buf, void __unused__ *bkg);
+herr_t H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
+ size_t nelmts, void *_buf, void __unused__ *bkg);
herr_t H5T_conv_float_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t nelmts, void *buf, void __unused__ *bkg);
herr_t H5T_conv_double_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index 822e053..f9d417b 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -64,22 +64,55 @@ typedef enum H5T_norm_t {
/*H5T_NORM_NONE must be last */
} H5T_norm_t;
-/* Character set to use for text strings */
+/*
+ * Character set to use for text strings. Do not change these values since
+ * they appear in HDF5 files!
+ */
typedef enum H5T_cset_t {
H5T_CSET_ERROR = -1, /*error */
H5T_CSET_ASCII = 0, /*US ASCII */
-
- H5T_NCSET = 1 /*this must be last! */
+ H5T_CSET_RESERVED_1 = 1, /*reserved for later use */
+ H5T_CSET_RESERVED_2 = 2, /*reserved for later use */
+ H5T_CSET_RESERVED_3 = 3, /*reserved for later use */
+ H5T_CSET_RESERVED_4 = 4, /*reserved for later use */
+ H5T_CSET_RESERVED_5 = 5, /*reserved for later use */
+ H5T_CSET_RESERVED_6 = 6, /*reserved for later use */
+ H5T_CSET_RESERVED_7 = 7, /*reserved for later use */
+ H5T_CSET_RESERVED_8 = 8, /*reserved for later use */
+ H5T_CSET_RESERVED_9 = 9, /*reserved for later use */
+ H5T_CSET_RESERVED_10 = 10, /*reserved for later use */
+ H5T_CSET_RESERVED_11 = 11, /*reserved for later use */
+ H5T_CSET_RESERVED_12 = 12, /*reserved for later use */
+ H5T_CSET_RESERVED_13 = 13, /*reserved for later use */
+ H5T_CSET_RESERVED_14 = 14, /*reserved for later use */
+ H5T_CSET_RESERVED_15 = 15 /*reserved for later use */
} H5T_cset_t;
+#define H5T_NCSET 1 /*Number of character sets actually defined */
-/* Type of padding to use in character strings */
+/*
+ * Type of padding to use in character strings. Do not change these values
+ * since they appear in HDF5 files!
+ */
typedef enum H5T_str_t {
H5T_STR_ERROR = -1, /*error */
- H5T_STR_NULL = 0, /*pad with null term like in C */
- H5T_STR_SPACE = 1, /*pad with spaces like in Fortran */
-
- H5T_NSTR = 2 /*this must be last! */
+ H5T_STR_NULLTERM = 0, /*null terminate like in C */
+ H5T_STR_NULLPAD = 1, /*pad with nulls */
+ H5T_STR_SPACEPAD = 2, /*pad with spaces like in Fortran */
+ H5T_STR_RESERVED_3 = 3, /*reserved for later use */
+ H5T_STR_RESERVED_4 = 4, /*reserved for later use */
+ H5T_STR_RESERVED_5 = 5, /*reserved for later use */
+ H5T_STR_RESERVED_6 = 6, /*reserved for later use */
+ H5T_STR_RESERVED_7 = 7, /*reserved for later use */
+ H5T_STR_RESERVED_8 = 8, /*reserved for later use */
+ H5T_STR_RESERVED_9 = 9, /*reserved for later use */
+ H5T_STR_RESERVED_10 = 10, /*reserved for later use */
+ H5T_STR_RESERVED_11 = 11, /*reserved for later use */
+ H5T_STR_RESERVED_12 = 12, /*reserved for later use */
+ H5T_STR_RESERVED_13 = 13, /*reserved for later use */
+ H5T_STR_RESERVED_14 = 14, /*reserved for later use */
+ H5T_STR_RESERVED_15 = 15 /*reserved for later use */
} H5T_str_t;
+#define H5T_NSTR 3 /*num H5T_str_t types actually defined */
/* Type of padding to use in other atomic types */
typedef enum H5T_pad_t {
diff --git a/test/.distdep b/test/.distdep
index 020d41a..48594df 100644
--- a/test/.distdep
+++ b/test/.distdep
@@ -178,33 +178,6 @@ th5s.o: \
../src/H5Tpublic.h \
../src/H5Zprivate.h \
../src/H5Zpublic.h
-dtypes.o: \
- dtypes.c \
- ../src/hdf5.h \
- ../src/H5public.h \
- ../src/H5config.h \
- ../src/H5Ipublic.h \
- ../src/H5Apublic.h \
- ../src/H5ACpublic.h \
- ../src/H5Bpublic.h \
- ../src/H5Dpublic.h \
- ../src/H5Epublic.h \
- ../src/H5Fpublic.h \
- ../src/H5Gpublic.h \
- ../src/H5HGpublic.h \
- ../src/H5HLpublic.h \
- ../src/H5MFpublic.h \
- ../src/H5MMpublic.h \
- ../src/H5Opublic.h \
- ../src/H5Ppublic.h \
- ../src/H5Zpublic.h \
- ../src/H5Spublic.h \
- ../src/H5Tpublic.h \
- ../src/H5Tpkg.h \
- ../src/H5HGprivate.h \
- ../src/H5Fprivate.h \
- ../src/H5private.h \
- ../src/H5Tprivate.h
hyperslab.o: \
hyperslab.c \
../src/H5private.h \
@@ -410,8 +383,24 @@ links.o: \
../src/H5Zpublic.h \
../src/H5Spublic.h \
../src/H5Tpublic.h
-chunk.o: \
- chunk.c \
+bittests.o: \
+ bittests.c \
+ ../src/H5Tpkg.h \
+ ../src/H5HGprivate.h \
+ ../src/H5HGpublic.h \
+ ../src/H5public.h \
+ ../src/H5config.h \
+ ../src/H5Fprivate.h \
+ ../src/H5Fpublic.h \
+ ../src/H5Ipublic.h \
+ ../src/H5private.h \
+ ../src/H5Dpublic.h \
+ ../src/H5Tprivate.h \
+ ../src/H5Tpublic.h \
+ ../src/H5Gprivate.h \
+ ../src/H5Gpublic.h
+mtime.o: \
+ mtime.c \
../src/hdf5.h \
../src/H5public.h \
../src/H5config.h \
@@ -431,25 +420,33 @@ chunk.o: \
../src/H5Ppublic.h \
../src/H5Zpublic.h \
../src/H5Spublic.h \
- ../src/H5Tpublic.h
-bittests.o: \
- bittests.c \
- ../src/H5Tpkg.h \
- ../src/H5HGprivate.h \
- ../src/H5HGpublic.h \
+ ../src/H5Tpublic.h \
+ ../src/H5private.h
+big.o: \
+ big.c \
+ ../src/hdf5.h \
../src/H5public.h \
../src/H5config.h \
- ../src/H5Fprivate.h \
- ../src/H5Fpublic.h \
../src/H5Ipublic.h \
- ../src/H5private.h \
+ ../src/H5Apublic.h \
+ ../src/H5ACpublic.h \
+ ../src/H5Bpublic.h \
../src/H5Dpublic.h \
- ../src/H5Tprivate.h \
+ ../src/H5Epublic.h \
+ ../src/H5Fpublic.h \
+ ../src/H5Gpublic.h \
+ ../src/H5HGpublic.h \
+ ../src/H5HLpublic.h \
+ ../src/H5MFpublic.h \
+ ../src/H5MMpublic.h \
+ ../src/H5Opublic.h \
+ ../src/H5Ppublic.h \
+ ../src/H5Zpublic.h \
+ ../src/H5Spublic.h \
../src/H5Tpublic.h \
- ../src/H5Gprivate.h \
- ../src/H5Gpublic.h
-mtime.o: \
- mtime.c \
+ ../src/H5private.h
+dtypes.o: \
+ dtypes.c \
../src/hdf5.h \
../src/H5public.h \
../src/H5config.h \
@@ -470,9 +467,13 @@ mtime.o: \
../src/H5Zpublic.h \
../src/H5Spublic.h \
../src/H5Tpublic.h \
- ../src/H5private.h
-big.o: \
- big.c \
+ ../src/H5Tpkg.h \
+ ../src/H5HGprivate.h \
+ ../src/H5Fprivate.h \
+ ../src/H5private.h \
+ ../src/H5Tprivate.h
+chunk.o: \
+ chunk.c \
../src/hdf5.h \
../src/H5public.h \
../src/H5config.h \
@@ -492,5 +493,4 @@ big.o: \
../src/H5Ppublic.h \
../src/H5Zpublic.h \
../src/H5Spublic.h \
- ../src/H5Tpublic.h \
- ../src/H5private.h
+ ../src/H5Tpublic.h
diff --git a/test/chunk.c b/test/chunk.c
index 73cb07c..60a8850 100644
--- a/test/chunk.c
+++ b/test/chunk.c
@@ -7,13 +7,8 @@
*
* Purpose: Checks the effect of various I/O request sizes and raw data
* cache sizes. Performance depends on the amount of data read
- * from disk, and we use a trick to get that number: a
- * compress/uncompress pair that counts the amount of data read.
- * Since the data itself is not important, the compression just
- * removes a byte and uncompression adds some byte of arbitrary
- * value. The change in size is necessary or the library will
- * not store the data as compressed and thus not call the
- * uncompression method.
+ * from disk and we use a filter to get that number.
+
*/
#include <assert.h>
#include <hdf5.h>
@@ -34,7 +29,7 @@
#define LINESPOINTS "lines"
#define CH_SIZE 100 /*squared in terms of bytes */
#define DS_SIZE 20 /*squared in terms of chunks */
-#define ZMETHNO H5Z_USERDEF_MIN
+#define FILTER_COUNTER 305
#define READ 0
#define WRITE 1
#define MIN(X,Y) ((X)<(Y)?(X):(Y))
@@ -62,9 +57,9 @@ static hid_t fapl_g = -1;
/*-------------------------------------------------------------------------
- * Function: count_c
+ * Function: counter
*
- * Purpose: A bogus compression method that just removes the last byte.
+ * Purpose: Count number of bytes but don't do anything.
*
* Return: Success: src_nbytes-1
*
@@ -78,41 +73,12 @@ static hid_t fapl_g = -1;
*-------------------------------------------------------------------------
*/
static size_t
-count_c (unsigned int __unused__ flags, size_t __unused__ cd_size,
- const void __unused__ *client_data, size_t src_nbytes,
- const void *src, size_t __unused__ dst_nbytes, void *dst/*out*/)
-{
- memcpy (dst, src, src_nbytes-1);
- nio_g += src_nbytes;
- return src_nbytes-1;
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: count_u
- *
- * Purpose: A bogus unompress method that just adds a zero to the end.
- *
- * Return: Success: src_nbytes+1
- *
- * Failure: never fails
- *
- * Programmer: Robb Matzke
- * Thursday, May 14, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static size_t
-count_u (unsigned int __unused__ flags, size_t __unused__ cd_size,
- const void __unused__ *client_data, size_t src_nbytes,
- const void *src, size_t __unused__ dst_nbytes, void *dst/*out*/)
+counter (unsigned __unused__ flags, size_t __unused__ cd_nelmts,
+ const unsigned __unused__ *cd_values, size_t nbytes,
+ size_t __unused__ *buf_size, void __unused__ **buf)
{
- memcpy (dst, src, src_nbytes);
- ((char*)dst)[src_nbytes] = 0;
- nio_g += src_nbytes+1;
- return src_nbytes+1;
+ nio_g += nbytes;
+ return nbytes;
}
@@ -151,8 +117,8 @@ create_dataset (void)
dcpl = H5Pcreate (H5P_DATASET_CREATE);
size[0] = size[1] = CH_SIZE;
H5Pset_chunk (dcpl, 2, size);
- H5Zregister (ZMETHNO, "counter", count_c, count_u);
- H5Pset_compression (dcpl, ZMETHNO, 0, 0, NULL);
+ H5Zregister (FILTER_COUNTER, "counter", counter);
+ H5Pset_filter (dcpl, FILTER_COUNTER, 0, 0, NULL);
/* The dataset */
dset = H5Dcreate (file, "dset", H5T_NATIVE_CHAR, space, dcpl);
@@ -214,7 +180,8 @@ test_rowmaj (int op, hsize_t cache_size, hsize_t io_size)
hs_offset[1] = j;
hs_size[1] = MIN (io_size, CH_SIZE*DS_SIZE-j);
mem_space = H5Screate_simple (2, hs_size, hs_size);
- H5Sselect_hyperslab (file_space, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL);
+ H5Sselect_hyperslab (file_space, H5S_SELECT_SET, hs_offset,
+ NULL, hs_size, NULL);
if (READ==op) {
H5Dread (dset, H5T_NATIVE_CHAR, mem_space, file_space,
@@ -274,7 +241,8 @@ test_diag (int op, hsize_t cache_size, hsize_t io_size, hsize_t offset)
hs_offset[0] = hs_offset[1] = i;
hs_size[0] = hs_size[1] = MIN (io_size, CH_SIZE*DS_SIZE-i);
mem_space = H5Screate_simple (2, hs_size, hs_size);
- H5Sselect_hyperslab (file_space, H5S_SELECT_SET, hs_offset, NULL, hs_size, NULL);
+ H5Sselect_hyperslab (file_space, H5S_SELECT_SET, hs_offset, NULL,
+ hs_size, NULL);
if (READ==op) {
H5Dread (dset, H5T_NATIVE_CHAR, mem_space, file_space,
H5P_DEFAULT, buf);
diff --git a/test/dtypes.c b/test/dtypes.c
index f06c8bb..320d440 100644
--- a/test/dtypes.c
+++ b/test/dtypes.c
@@ -681,6 +681,343 @@ test_named (void)
/*-------------------------------------------------------------------------
+ * Function: mkstr
+ *
+ * Purpose: Create a new string data type
+ *
+ * Return: Success: New type
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Monday, August 10, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+mkstr(size_t len, H5T_str_t strpad)
+{
+ hid_t t;
+
+ if ((t=H5Tcopy(H5T_C_S1))<0) return -1;
+ if (H5Tset_size(t, len)<0) return -1;
+ if (H5Tset_strpad(t, strpad)<0) return -1;
+ return t;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_conv_str_1
+ *
+ * Purpose: Test string conversions
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Monday, August 10, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_conv_str_1(void)
+{
+ char *buf=NULL;
+ hid_t src_type, dst_type;
+
+ printf("%-70s", "Testing string conversions");
+ fflush(stdout);
+
+ /*
+ * Convert a null-terminated string to a shorter and longer null
+ * terminated string.
+ */
+ src_type = mkstr(10, H5T_STR_NULLTERM);
+ dst_type = mkstr(5, H5T_STR_NULLTERM);
+ buf = calloc(2, 10);
+ memcpy(buf, "abcdefghi\0abcdefghi\0", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcd\0abcd\0abcdefghi\0", 20)) {
+ puts("*FAILED*");
+ puts(" Truncated C-string test failed");
+ goto error;
+ }
+ if (H5Tconvert(dst_type, src_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcd\0\0\0\0\0\0abcd\0\0\0\0\0\0", 20)) {
+ puts("*FAILED*");
+ puts(" Extended C-string test failed");
+ goto error;
+ }
+ free(buf);
+ H5Tclose(src_type);
+ H5Tclose(dst_type);
+
+ /*
+ * Convert a null padded string to a shorter and then longer string.
+ */
+ src_type = mkstr(10, H5T_STR_NULLPAD);
+ dst_type = mkstr(5, H5T_STR_NULLPAD);
+ buf = calloc(2, 10);
+ memcpy(buf, "abcdefghijabcdefghij", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcdeabcdeabcdefghij", 20)) {
+ puts("*FAILED*");
+ puts(" Truncated C buffer test failed");
+ goto error;
+ }
+ if (H5Tconvert(dst_type, src_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcde\0\0\0\0\0abcde\0\0\0\0\0", 20)) {
+ puts("*FAILED*");
+ puts(" Extended C buffer test failed");
+ goto error;
+ }
+ free(buf);
+ H5Tclose(src_type);
+ H5Tclose(dst_type);
+
+ /*
+ * Convert a space-padded string to a shorter and then longer string.
+ */
+ src_type = mkstr(10, H5T_STR_SPACEPAD);
+ dst_type = mkstr(5, H5T_STR_SPACEPAD);
+ buf = calloc(2, 10);
+ memcpy(buf, "abcdefghijabcdefghij", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcdeabcdeabcdefghij", 20)) {
+ puts("*FAILED*");
+ puts(" Truncated Fortran-string test failed");
+ goto error;
+ }
+ if (H5Tconvert(dst_type, src_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcde abcde ", 20)) {
+ puts("*FAILED*");
+ puts(" Extended Fortran-string test failed");
+ goto error;
+ }
+ free(buf);
+ H5Tclose(src_type);
+ H5Tclose(dst_type);
+
+ /*
+ * What happens if a null-terminated string is not null terminated? If
+ * the conversion is to an identical string then nothing happens but if
+ * the destination is a different size or type of string then the right
+ * thing should happen.
+ */
+ src_type = mkstr(10, H5T_STR_NULLTERM);
+ dst_type = mkstr(10, H5T_STR_NULLTERM);
+ buf = calloc(2, 10);
+ memcpy(buf, "abcdefghijabcdefghij", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcdefghijabcdefghij", 20)) {
+ puts("*FAILED*");
+ puts(" Non-terminated string test 1");
+ goto error;
+ }
+ H5Tclose(dst_type);
+ dst_type = mkstr(5, H5T_STR_NULLTERM);
+ memcpy(buf, "abcdefghijabcdefghij", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcd\0abcd\0abcdefghij", 20)) {
+ puts("*FAILED*");
+ puts(" Non-terminated string test 2");
+ goto error;
+ }
+ memcpy(buf, "abcdeabcdexxxxxxxxxx", 20);
+ if (H5Tconvert(dst_type, src_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcde\0\0\0\0\0abcde\0\0\0\0\0", 20)) {
+ puts("*FAILED*");
+ puts(" Non-terminated string test 2");
+ goto error;
+ }
+ free(buf);
+ H5Tclose(src_type);
+ H5Tclose(dst_type);
+
+ /*
+ * Test C string to Fortran and vice versa.
+ */
+ src_type = mkstr(10, H5T_STR_NULLTERM);
+ dst_type = mkstr(10, H5T_STR_SPACEPAD);
+ buf = calloc(2, 10);
+ memcpy(buf, "abcdefghi\0abcdefghi\0", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcdefghi abcdefghi ", 20)) {
+ puts("*FAILED*");
+ puts(" C string to Fortran test 1");
+ goto error;
+ }
+ if (H5Tconvert(dst_type, src_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcdefghi\0abcdefghi\0", 20)) {
+ puts("*FAILED*");
+ puts(" Fortran to C string test 1");
+ goto error;
+ }
+ H5Tclose(dst_type);
+ dst_type = mkstr(5, H5T_STR_SPACEPAD);
+ memcpy(buf, "abcdefgh\0\0abcdefgh\0\0", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcdeabcdeabcdefgh\0\0", 20)) {
+ puts("*FAILED*");
+ puts(" C string to Fortran test 2");
+ goto error;
+ }
+ if (H5Tconvert(dst_type, src_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcde\0\0\0\0\0abcde\0\0\0\0\0", 20)) {
+ puts("*FAILED*");
+ puts(" Fortran to C string test 2");
+ goto error;
+ }
+ H5Tclose(src_type);
+ H5Tclose(dst_type);
+ src_type = mkstr(5, H5T_STR_NULLTERM);
+ dst_type = mkstr(10, H5T_STR_SPACEPAD);
+ memcpy(buf, "abcd\0abcd\0xxxxxxxxxx", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcd abcd ", 20)) {
+ puts("*FAILED*");
+ puts(" C string to Fortran test 3");
+ goto error;
+ }
+ if (H5Tconvert(dst_type, src_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcd\0abcd\0abcd ", 20)) {
+ puts("*FAILED*");
+ puts(" Fortran to C string test 3");
+ goto error;
+ }
+ free(buf);
+ H5Tclose(src_type);
+ H5Tclose(dst_type);
+
+ /*
+ * Test C buffer to Fortran and vice versa.
+ */
+ src_type = mkstr(10, H5T_STR_NULLPAD);
+ dst_type = mkstr(10, H5T_STR_SPACEPAD);
+ buf = calloc(2, 10);
+ memcpy(buf, "abcdefghijabcdefghij", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcdefghijabcdefghij", 20)) {
+ puts("*FAILED*");
+ puts(" C buffer to Fortran test 1");
+ goto error;
+ }
+ if (H5Tconvert(dst_type, src_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcdefghijabcdefghij", 20)) {
+ puts("*FAILED*");
+ puts(" Fortran to C buffer test 1");
+ goto error;
+ }
+ H5Tclose(dst_type);
+ dst_type = mkstr(5, H5T_STR_SPACEPAD);
+ memcpy(buf, "abcdefgh\0\0abcdefgh\0\0", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcdeabcdeabcdefgh\0\0", 20)) {
+ puts("*FAILED*");
+ puts(" C buffer to Fortran test 2");
+ goto error;
+ }
+ if (H5Tconvert(dst_type, src_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcde\0\0\0\0\0abcde\0\0\0\0\0", 20)) {
+ puts("*FAILED*");
+ puts(" Fortran to C buffer test 2");
+ goto error;
+ }
+ H5Tclose(src_type);
+ H5Tclose(dst_type);
+ src_type = mkstr(5, H5T_STR_NULLPAD);
+ dst_type = mkstr(10, H5T_STR_SPACEPAD);
+ memcpy(buf, "abcd\0abcd\0xxxxxxxxxx", 20);
+ if (H5Tconvert(src_type, dst_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcd abcd ", 20)) {
+ puts("*FAILED*");
+ puts(" C buffer to Fortran test 3");
+ goto error;
+ }
+ if (H5Tconvert(dst_type, src_type, 2, buf, NULL)<0) goto error;
+ if (memcmp(buf, "abcd\0abcd\0abcd ", 20)) {
+ puts("*FAILED*");
+ puts(" Fortran to C buffer test 3");
+ goto error;
+ }
+ free(buf);
+ H5Tclose(src_type);
+ H5Tclose(dst_type);
+
+ puts(" PASSED");
+ return 0;
+
+ error:
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_conv_str_2
+ *
+ * Purpose: Tests C-to-Fortran and Fortran-to-C string conversion speed.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Monday, August 10, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_conv_str_2(void)
+{
+ char *buf=NULL, s[80];
+ hid_t c_type, f_type;
+ const size_t nelmts = 200000, ntests=5;
+ size_t i, j, nchars;
+ herr_t ret_value = -1;
+
+ /*
+ * Initialize types and buffer.
+ */
+ c_type = mkstr(8, H5T_STR_NULLPAD);
+ f_type = mkstr(8, H5T_STR_SPACEPAD);
+ buf = calloc(nelmts, 8);
+ for (i=0; i<nelmts; i++) {
+ nchars = rand() % 8;
+ for (j=0; j<nchars; j++) {
+ buf[i*8+j] = 'a' + rand()%26;
+ }
+ while (j<nchars) buf[i*8+j++] = '\0';
+ }
+
+ /* Do the conversions */
+ for (i=0; i<ntests; i++) {
+ sprintf(s, "Testing random string conversion speed (test %d/%d)",
+ (int)(i+1), (int)ntests);
+ printf("%-70s", s);
+ fflush(stdout);
+
+ if (H5Tconvert(c_type, f_type, nelmts, buf, NULL)<0) goto error;
+ if (H5Tconvert(f_type, c_type, nelmts, buf, NULL)<0) goto error;
+ puts(" PASSED");
+ }
+ ret_value = 0;
+
+ error:
+ if (buf) free(buf);
+ return ret_value;
+}
+
+
+
+
+/*-------------------------------------------------------------------------
* Function: test_conv_int
*
* Purpose: Test atomic number conversions.
@@ -1310,6 +1647,8 @@ main(void)
nerrors += test_compound()<0 ? 1 : 0;
nerrors += test_transient ()<0 ? 1 : 0;
nerrors += test_named ()<0 ? 1 : 0;
+ nerrors += test_conv_str_1()<0 ? 1 : 0;
+ nerrors += test_conv_str_2()<0 ? 1 : 0;
nerrors += test_conv_int ()<0 ? 1 : 0;
/* Does floating point overflow generate a SIGFPE? */