summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2007-12-17 18:58:23 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2007-12-17 18:58:23 (GMT)
commita3fb4efb4dc0194c0d072716f7fb80cdf875805e (patch)
treef1757636e82a523fda74f1b85fd9e331afc9d496
parent6036ac9b307ddb1192afd3988d20111766b1e258 (diff)
downloadhdf5-a3fb4efb4dc0194c0d072716f7fb80cdf875805e.zip
hdf5-a3fb4efb4dc0194c0d072716f7fb80cdf875805e.tar.gz
hdf5-a3fb4efb4dc0194c0d072716f7fb80cdf875805e.tar.bz2
[svn-r14349] This is the first commit after branching out the feature of the filter for modifying dataset's
datatype. There seems a lot of changes. Basically, this feature allows an application to change the datatypes of datasets. If the dataset is chunked and this filter is enabled, the modification of the data is until new data is written to the file. If the dataset is contiguous or compact, the data is converted immediately when H5Dmodify_dtype is called. I've tested it on 3 platforms. But there'll be some more changes coming. There'll be more thorough test later.
-rw-r--r--MANIFEST1
-rw-r--r--Makefile.in1
-rw-r--r--c++/Makefile.in1
-rw-r--r--c++/examples/Makefile.in1
-rw-r--r--c++/src/Makefile.in1
-rw-r--r--c++/test/Makefile.in1
-rw-r--r--c++/test/dsets.cpp1
-rw-r--r--c++/test/tfilter.cpp1
-rwxr-xr-xconfigure64
-rw-r--r--configure.in10
-rw-r--r--examples/Makefile.in1
-rw-r--r--fortran/Makefile.in1
-rw-r--r--fortran/examples/Makefile.in1
-rw-r--r--fortran/src/Makefile.in1
-rw-r--r--fortran/test/Makefile.in1
-rw-r--r--fortran/testpar/Makefile.in1
-rwxr-xr-xhl/Makefile.in1
-rw-r--r--hl/c++/Makefile.in1
-rw-r--r--hl/c++/examples/Makefile.in1
-rw-r--r--hl/c++/src/Makefile.in1
-rw-r--r--hl/c++/test/Makefile.in1
-rw-r--r--hl/examples/Makefile.in1
-rw-r--r--hl/fortran/Makefile.in1
-rw-r--r--hl/fortran/examples/Makefile.in1
-rw-r--r--hl/fortran/src/Makefile.in1
-rw-r--r--hl/fortran/test/Makefile.in1
-rw-r--r--hl/src/Makefile.in1
-rw-r--r--hl/test/Makefile.in1
-rw-r--r--hl/tools/Makefile.in1
-rw-r--r--hl/tools/gif2h5/Makefile.in1
-rw-r--r--perform/Makefile.in1
-rw-r--r--src/H5Abtree2.c2
-rw-r--r--src/H5Adense.c2
-rw-r--r--src/H5Dcompact.c123
-rw-r--r--src/H5Dcontig.c186
-rw-r--r--src/H5Ddeprec.c5
-rw-r--r--src/H5Dint.c68
-rw-r--r--src/H5Dio.c586
-rw-r--r--src/H5Distore.c399
-rw-r--r--src/H5Dpkg.h8
-rw-r--r--src/H5Dprivate.h6
-rw-r--r--src/H5Dpublic.h1
-rw-r--r--src/H5Gbtree2.c2
-rw-r--r--src/H5Gdense.c10
-rw-r--r--src/H5HFcache.c2
-rw-r--r--src/H5Olayout.c16
-rw-r--r--src/H5Omessage.c9
-rw-r--r--src/H5Oprivate.h2
-rw-r--r--src/H5Oshared.c4
-rw-r--r--src/H5Pdcpl.c54
-rw-r--r--src/H5Pdxpl.c8
-rw-r--r--src/H5Ppublic.h1
-rw-r--r--src/H5S.c2
-rwxr-xr-xsrc/H5SM.c2
-rw-r--r--src/H5T.c411
-rw-r--r--src/H5Tcompound.c2
-rw-r--r--src/H5Tfloat.c44
-rw-r--r--src/H5Tprecis.c2
-rw-r--r--src/H5Tprivate.h6
-rw-r--r--src/H5Tvlen.c8
-rw-r--r--src/H5Z.c83
-rw-r--r--src/H5Zdeflate.c1
-rw-r--r--src/H5Zfletcher32.c1
-rw-r--r--src/H5Znbit.c12
-rw-r--r--src/H5Zpkg.h11
-rw-r--r--src/H5Zprivate.h5
-rw-r--r--src/H5Zpublic.h28
-rw-r--r--src/H5Zscaleoffset.c13
-rw-r--r--src/H5Zshuffle.c1
-rw-r--r--src/H5Zszip.c12
-rw-r--r--src/H5config.h.in3
-rwxr-xr-xsrc/Makefile.am2
-rw-r--r--src/Makefile.in9
-rw-r--r--test/Makefile.am4
-rw-r--r--test/Makefile.in61
-rw-r--r--test/change_dtypes.c764
-rw-r--r--test/cmpd_dset.c990
-rw-r--r--test/dsets.c325
-rw-r--r--test/tvltypes.c285
-rw-r--r--testpar/Makefile.in1
-rw-r--r--testpar/t_dset.c4
-rw-r--r--testpar/testphdf5.c12
-rw-r--r--tools/Makefile.in1
-rw-r--r--tools/h5copy/Makefile.in1
-rw-r--r--tools/h5diff/Makefile.in1
-rw-r--r--tools/h5dump/Makefile.in1
-rw-r--r--tools/h5dump/h5dump.c4
-rw-r--r--tools/h5dump/h5dump.h1
-rw-r--r--tools/h5dump/h5dumpgentest.c8
-rwxr-xr-xtools/h5import/Makefile.in1
-rw-r--r--tools/h5jam/Makefile.in1
-rw-r--r--tools/h5ls/Makefile.in1
-rw-r--r--tools/h5repack/Makefile.in1
-rw-r--r--tools/h5stat/Makefile.in1
-rw-r--r--tools/lib/Makefile.in1
-rw-r--r--tools/lib/h5tools_filters.c27
-rw-r--r--tools/misc/Makefile.in1
97 files changed, 4437 insertions, 315 deletions
diff --git a/MANIFEST b/MANIFEST
index e995e3e..a747c88 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -736,6 +736,7 @@
./test/cache_api.c
./test/cache_common.c
./test/cache_common.h
+./test/change_dtypes.c
./test/cmpd_dset.c
./test/cross_read.c
./test/dangle.c
diff --git a/Makefile.in b/Makefile.in
index e8f00c0..cba76ef 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -227,6 +227,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/c++/Makefile.in b/c++/Makefile.in
index be2bab8..d2935a9 100644
--- a/c++/Makefile.in
+++ b/c++/Makefile.in
@@ -198,6 +198,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/c++/examples/Makefile.in b/c++/examples/Makefile.in
index e6b643a..b19ded1 100644
--- a/c++/examples/Makefile.in
+++ b/c++/examples/Makefile.in
@@ -192,6 +192,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/c++/src/Makefile.in b/c++/src/Makefile.in
index de7cc10..fa03f72 100644
--- a/c++/src/Makefile.in
+++ b/c++/src/Makefile.in
@@ -228,6 +228,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/c++/test/Makefile.in b/c++/test/Makefile.in
index 7cd387f..a628955 100644
--- a/c++/test/Makefile.in
+++ b/c++/test/Makefile.in
@@ -214,6 +214,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp
index 652149e..97ba6ca 100644
--- a/c++/test/dsets.cpp
+++ b/c++/test/dsets.cpp
@@ -359,6 +359,7 @@ const H5Z_class_t H5Z_BOGUS[1] = {{
"bogus", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
(H5Z_func_t)filter_bogus, /* The actual filter function */
}};
diff --git a/c++/test/tfilter.cpp b/c++/test/tfilter.cpp
index 1774cf2..a667f2a 100644
--- a/c++/test/tfilter.cpp
+++ b/c++/test/tfilter.cpp
@@ -67,6 +67,7 @@ const H5Z_class_t H5Z_BOGUS[1] = {{
"bogus", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
(H5Z_func_t)filter_bogus, /* The actual filter function */
}};
diff --git a/configure b/configure
index 1347fae..aee5c5b 100755
--- a/configure
+++ b/configure
@@ -928,6 +928,7 @@ USE_FILTER_SHUFFLE
USE_FILTER_FLETCHER32
USE_FILTER_NBIT
USE_FILTER_SCALEOFFSET
+USE_FILTER_DTYPE_MODIFY
DIRECT_VFD_CONDITIONAL_TRUE
DIRECT_VFD_CONDITIONAL_FALSE
H5_VERSION
@@ -1603,7 +1604,8 @@ Optional Features:
[default=yes]
--enable-filters=all Turn on all internal I/O filters. One may also
specify a comma-separated list of filters or the
- word no. The default is all internal I/O filters.
+ word no. The default is with all internal I/O
+ filters.
--enable-direct-vfd Build the Direct I/O Virtual File Driver
[default=yes]
--enable-dconv-exception
@@ -7923,7 +7925,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 7926 "configure"' > conftest.$ac_ext
+ echo '#line 7928 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -10197,11 +10199,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:10200: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:10202: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:10204: \$? = $ac_status" >&5
+ echo "$as_me:10206: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -10465,11 +10467,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:10468: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:10470: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:10472: \$? = $ac_status" >&5
+ echo "$as_me:10474: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -10569,11 +10571,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:10572: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:10574: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:10576: \$? = $ac_status" >&5
+ echo "$as_me:10578: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -12949,7 +12951,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 12952 "configure"
+#line 12954 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13049,7 +13051,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 13052 "configure"
+#line 13054 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -15401,11 +15403,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15404: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15406: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:15408: \$? = $ac_status" >&5
+ echo "$as_me:15410: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -15505,11 +15507,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15508: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15510: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:15512: \$? = $ac_status" >&5
+ echo "$as_me:15514: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -17075,11 +17077,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17078: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17080: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17082: \$? = $ac_status" >&5
+ echo "$as_me:17084: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -17179,11 +17181,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17182: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17184: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:17186: \$? = $ac_status" >&5
+ echo "$as_me:17188: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -19377,11 +19379,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:19380: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:19382: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:19384: \$? = $ac_status" >&5
+ echo "$as_me:19386: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -19645,11 +19647,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:19648: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:19650: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:19652: \$? = $ac_status" >&5
+ echo "$as_me:19654: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -19749,11 +19751,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:19752: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:19754: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:19756: \$? = $ac_status" >&5
+ echo "$as_me:19758: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -50436,6 +50438,7 @@ fi
USE_FILTER_FLETCHER32="no"
USE_FILTER_NBIT="no"
USE_FILTER_SCALEOFFSET="no"
+ USE_FILTER_DTYPE_MODIFY="no"
{ echo "$as_me:$LINENO: checking for I/O filters" >&5
echo $ECHO_N "checking for I/O filters... $ECHO_C" >&6; }
# Check whether --enable-filters was given.
@@ -50444,7 +50447,7 @@ if test "${enable_filters+set}" = set; then
fi
-all_filters="shuffle,fletcher32,nbit,scaleoffset"
+all_filters="shuffle,fletcher32,nbit,scaleoffset,dtype_modify"
case "X-$FILTERS" in
X-|X-all)
FILTERS=$all_filters
@@ -50496,6 +50499,14 @@ _ACEOF
USE_FILTER_SCALEOFFSET="yes"
fi
+ if test $filter = "DTYPE_MODIFY"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FILTER_DTYPE_MODIFY 1
+_ACEOF
+
+ USE_FILTER_DTYPE_MODIFY="yes"
+ fi
done
fi
@@ -53126,6 +53137,7 @@ USE_FILTER_SHUFFLE!$USE_FILTER_SHUFFLE$ac_delim
USE_FILTER_FLETCHER32!$USE_FILTER_FLETCHER32$ac_delim
USE_FILTER_NBIT!$USE_FILTER_NBIT$ac_delim
USE_FILTER_SCALEOFFSET!$USE_FILTER_SCALEOFFSET$ac_delim
+USE_FILTER_DTYPE_MODIFY!$USE_FILTER_DTYPE_MODIFY$ac_delim
DIRECT_VFD_CONDITIONAL_TRUE!$DIRECT_VFD_CONDITIONAL_TRUE$ac_delim
DIRECT_VFD_CONDITIONAL_FALSE!$DIRECT_VFD_CONDITIONAL_FALSE$ac_delim
H5_VERSION!$H5_VERSION$ac_delim
@@ -53157,7 +53169,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 89; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 90; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index 956ebe9..996fb74 100644
--- a/configure.in
+++ b/configure.in
@@ -2596,17 +2596,18 @@ AC_SUBST(USE_FILTER_SHUFFLE) USE_FILTER_SHUFFLE="no"
AC_SUBST(USE_FILTER_FLETCHER32) USE_FILTER_FLETCHER32="no"
AC_SUBST(USE_FILTER_NBIT) USE_FILTER_NBIT="no"
AC_SUBST(USE_FILTER_SCALEOFFSET) USE_FILTER_SCALEOFFSET="no"
+AC_SUBST(USE_FILTER_DTYPE_MODIFY) USE_FILTER_DTYPE_MODIFY="no"
AC_MSG_CHECKING([for I/O filters])
AC_ARG_ENABLE([filters],
[AC_HELP_STRING([--enable-filters=all],
[Turn on all internal I/O filters. One may
also specify a comma-separated list of filters
- or the word no. The default is all internal
+ or the word no. The default is with all internal
I/O filters.])],
[FILTERS=$enableval])
dnl Eventually: all_filters="shuffle,foo,bar,baz"
-all_filters="shuffle,fletcher32,nbit,scaleoffset"
+all_filters="shuffle,fletcher32,nbit,scaleoffset,dtype_modify"
case "X-$FILTERS" in
X-|X-all)
FILTERS=$all_filters
@@ -2647,6 +2648,11 @@ if test -n "$FILTERS"; then
[Define if support for scaleoffset filter is enabled])
USE_FILTER_SCALEOFFSET="yes"
fi
+ if test $filter = "DTYPE_MODIFY"; then
+ AC_DEFINE([HAVE_FILTER_DTYPE_MODIFY], [1],
+ [Define if support for datatype modification filter is enabled])
+ USE_FILTER_DTYPE_MODIFY="yes"
+ fi
done
fi
diff --git a/examples/Makefile.in b/examples/Makefile.in
index f456fff..fa76b36 100644
--- a/examples/Makefile.in
+++ b/examples/Makefile.in
@@ -192,6 +192,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/fortran/Makefile.in b/fortran/Makefile.in
index 2d1edc6..c422666 100644
--- a/fortran/Makefile.in
+++ b/fortran/Makefile.in
@@ -202,6 +202,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/fortran/examples/Makefile.in b/fortran/examples/Makefile.in
index 217ef52..8a4cd54 100644
--- a/fortran/examples/Makefile.in
+++ b/fortran/examples/Makefile.in
@@ -192,6 +192,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/fortran/src/Makefile.in b/fortran/src/Makefile.in
index 1862f18..d4f3ec6 100644
--- a/fortran/src/Makefile.in
+++ b/fortran/src/Makefile.in
@@ -255,6 +255,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/fortran/test/Makefile.in b/fortran/test/Makefile.in
index 30dd71c..53245f6 100644
--- a/fortran/test/Makefile.in
+++ b/fortran/test/Makefile.in
@@ -248,6 +248,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/fortran/testpar/Makefile.in b/fortran/testpar/Makefile.in
index 53583e2..d7b50cb 100644
--- a/fortran/testpar/Makefile.in
+++ b/fortran/testpar/Makefile.in
@@ -205,6 +205,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/Makefile.in b/hl/Makefile.in
index ab0b512..10d95d5 100755
--- a/hl/Makefile.in
+++ b/hl/Makefile.in
@@ -202,6 +202,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/c++/Makefile.in b/hl/c++/Makefile.in
index c9ae4f2..9e385cc 100644
--- a/hl/c++/Makefile.in
+++ b/hl/c++/Makefile.in
@@ -198,6 +198,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/c++/examples/Makefile.in b/hl/c++/examples/Makefile.in
index a540e06..49fd057 100644
--- a/hl/c++/examples/Makefile.in
+++ b/hl/c++/examples/Makefile.in
@@ -192,6 +192,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/c++/src/Makefile.in b/hl/c++/src/Makefile.in
index ef44a6c..5825216 100644
--- a/hl/c++/src/Makefile.in
+++ b/hl/c++/src/Makefile.in
@@ -217,6 +217,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/c++/test/Makefile.in b/hl/c++/test/Makefile.in
index 8439ff5..070024d 100644
--- a/hl/c++/test/Makefile.in
+++ b/hl/c++/test/Makefile.in
@@ -208,6 +208,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/examples/Makefile.in b/hl/examples/Makefile.in
index a5a4d4f..3305e0f 100644
--- a/hl/examples/Makefile.in
+++ b/hl/examples/Makefile.in
@@ -192,6 +192,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/fortran/Makefile.in b/hl/fortran/Makefile.in
index 8125e3b..4a3343b 100644
--- a/hl/fortran/Makefile.in
+++ b/hl/fortran/Makefile.in
@@ -202,6 +202,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/fortran/examples/Makefile.in b/hl/fortran/examples/Makefile.in
index d4f12d0..6921a0a 100644
--- a/hl/fortran/examples/Makefile.in
+++ b/hl/fortran/examples/Makefile.in
@@ -192,6 +192,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/fortran/src/Makefile.in b/hl/fortran/src/Makefile.in
index a126837..c42f2b5 100644
--- a/hl/fortran/src/Makefile.in
+++ b/hl/fortran/src/Makefile.in
@@ -222,6 +222,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/fortran/test/Makefile.in b/hl/fortran/test/Makefile.in
index 2322eea..319354d 100644
--- a/hl/fortran/test/Makefile.in
+++ b/hl/fortran/test/Makefile.in
@@ -212,6 +212,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/src/Makefile.in b/hl/src/Makefile.in
index 278d5bf..bd569fe 100644
--- a/hl/src/Makefile.in
+++ b/hl/src/Makefile.in
@@ -218,6 +218,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/test/Makefile.in b/hl/test/Makefile.in
index 19c1de4..75704c9 100644
--- a/hl/test/Makefile.in
+++ b/hl/test/Makefile.in
@@ -228,6 +228,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/tools/Makefile.in b/hl/tools/Makefile.in
index dc1f4f6..8da86f5 100644
--- a/hl/tools/Makefile.in
+++ b/hl/tools/Makefile.in
@@ -199,6 +199,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/hl/tools/gif2h5/Makefile.in b/hl/tools/gif2h5/Makefile.in
index 84c03cd..3321ff5 100644
--- a/hl/tools/gif2h5/Makefile.in
+++ b/hl/tools/gif2h5/Makefile.in
@@ -220,6 +220,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/perform/Makefile.in b/perform/Makefile.in
index 33998c4..6d74eda 100644
--- a/perform/Makefile.in
+++ b/perform/Makefile.in
@@ -243,6 +243,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/src/H5Abtree2.c b/src/H5Abtree2.c
index b685af7..eacd16b 100644
--- a/src/H5Abtree2.c
+++ b/src/H5Abtree2.c
@@ -168,7 +168,7 @@ H5A_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata)
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_fh_name_cmp)
/* Decode attribute information */
- if(NULL == (attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)obj)))
+ if(NULL == (attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)obj, H5O_MSG_FLAG_WAS_UNKNOWN)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "can't decode attribute")
/* Compare the string values */
diff --git a/src/H5Adense.c b/src/H5Adense.c
index de6bc8c..f3eeed8 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -803,7 +803,7 @@ H5A_dense_copy_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
* HDF5 routine, it could attempt to re-protect that direct block for the
* heap, causing the HDF5 routine called to fail)
*/
- if(NULL == (udata->attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)obj)))
+ if(NULL == (udata->attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)obj, H5O_MSG_FLAG_WAS_UNKNOWN)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, FAIL, "can't decode attribute")
/* Set the creation order index for the attribute */
diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c
index 2e4d3f7..2ffeb1e 100644
--- a/src/H5Dcompact.c
+++ b/src/H5Dcompact.c
@@ -380,3 +380,126 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_compact_copy() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_compact_copy_conv
+ *
+ * Purpose: Copies compact data from SRC dataset to DST dataset
+ * and does data conversion. This function is similar to
+ * H5D_compact_copy and is mainly used by H5Dmodify_dtype.
+ *
+ * Return: Non-negative on success.
+ * Negative on failure.
+ *
+ * Programmer: Raymond Lu
+ * 8 October 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_compact_copy_conv(const H5D_t *dset_src, const H5D_t *dset_dst,
+ H5O_copy_t UNUSED *cpy_info, hid_t dxpl_id)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5T_path_t *tpath = NULL; /* Datatype conversion paths */
+ H5T_t *dt_src = NULL; /* Source datatype */
+ H5T_t *dt_dst = NULL; /* Destination datatype */
+ hid_t tid_src = -1; /* Datatype ID for source datatype */
+ hid_t tid_dst = -1; /* Datatype ID for destination datatype */
+ size_t src_dt_size = 0; /* Source datatype size */
+ size_t dst_dt_size = 0; /* Destination datatype size */
+ size_t max_dt_size; /* Max. datatype size */
+ hsize_t nelmts = 0; /* Number of elements in buffer */
+ hssize_t snelmts = 0; /* Number of elements in buffer */
+ hsize_t total_nbytes; /* Total number of bytes to copy */
+ hsize_t total_src_nbytes; /* Total number of bytes of the source */
+ hsize_t total_dst_nbytes; /* Total number of bytes of the destination */
+ void *buf = NULL; /* Buffer for copying data */
+ void *bkg = NULL; /* Temporary buffer for copying data */
+ hbool_t is_vlen = FALSE; /* Flag to indicate VL type */
+ hbool_t vlen_conv = TRUE; /* Transfer property to indicate no conversion for vlen */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_compact_copy_conv, FAIL)
+
+ /* Check args */
+ HDassert(dset_src && H5D_COMPACT == dset_src->shared->layout.type);
+ HDassert(dset_dst && H5D_COMPACT == dset_dst->shared->layout.type);
+
+ /* dataset pointers and IDs */
+ dt_src = dset_src->shared->type;
+ dt_dst = dset_dst->shared->type;
+ tid_src = dset_src->shared->type_id;
+ tid_dst = dset_dst->shared->type_id;
+
+ /* Set up number of bytes to copy, and initial buffer size */
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(dset_src->shared->space)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection")
+ H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,hsize_t);
+
+ if(nelmts==0)
+ HGOTO_DONE(SUCCEED)
+
+ /* Compute element sizes and other parameters */
+ src_dt_size = H5T_get_size(dt_src);
+ dst_dt_size = H5T_get_size(dt_dst);
+ max_dt_size = MAX(src_dt_size, dst_dt_size);
+
+ total_src_nbytes = nelmts*src_dt_size;
+ total_dst_nbytes = nelmts*dst_dt_size;
+ total_nbytes = MAX(total_src_nbytes, total_dst_nbytes);
+
+ /* If the datatype is or contains vlen, set the property to indicate no conversion
+ * is needed. */
+ if((is_vlen = H5T_detect_class(dt_src, H5T_VLEN)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to detect dtatypes")
+
+ if(is_vlen ) {
+ vlen_conv = FALSE;
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ if(H5P_set(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "Error setting vlen conv flag")
+ }
+
+ /* Set up the conversion functions */
+ if(NULL == (tpath = H5T_path_find(dt_src, dt_dst, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
+
+ /* Allocate memory for copying the chunk */
+ if(NULL == (buf = H5FL_BLK_MALLOC(type_conv, (size_t)total_nbytes)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* allocate temporary bkg buff for data conversion */
+ if(NULL == (bkg = H5FL_BLK_CALLOC(type_conv, (size_t)total_nbytes)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Copy the data into the conversion buffer */
+ HDmemcpy(buf, dset_src->shared->layout.u.compact.buf, (size_t)total_src_nbytes);
+
+ /* Convert from source file to destination file */
+ if(H5T_convert(tpath, tid_src, tid_dst, (size_t)nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
+
+ /* Set the property of vlen conversion back to normal */
+ if(is_vlen ) {
+ vlen_conv = TRUE;
+
+ if(H5P_set(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "Error setting vlen conv flag")
+ }
+
+ /* Copy the data from the conversion buffer to the destination */
+ dset_dst->shared->layout.u.compact.size = total_dst_nbytes;
+ dset_dst->shared->layout.u.compact.buf = (void*)H5MM_malloc((size_t)total_dst_nbytes);
+ HDmemcpy(dset_dst->shared->layout.u.compact.buf, buf, (size_t)total_dst_nbytes);
+
+done:
+ if(buf)
+ H5FL_BLK_FREE(type_conv, buf);
+ if(bkg)
+ H5FL_BLK_FREE(type_conv, bkg);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_compact_copy_conv() */
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index bdb8294..065450f 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -1212,3 +1212,189 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_contig_copy() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_contig_copy_conv
+ *
+ * Purpose: Copies contiguous data from SRC file to DST file
+ * and does data conversion. This function is similar to
+ * H5D_contig_copy and is mainly used by H5Dmodify_dtype.
+ *
+ * Return: Non-negative on success.
+ * Negative on failure.
+ *
+ * Programmer: Raymond Lu
+ * 8 October 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_contig_copy_conv(H5F_t *file, const H5D_t *dset_src, const H5D_t *dset_dst,
+ H5O_copy_t UNUSED *cpy_info, hid_t dxpl_id)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ haddr_t addr_src; /* File offset in source dataset */
+ haddr_t addr_dst; /* File offset in destination dataset */
+ H5T_path_t *tpath = NULL; /* Datatype conversion paths */
+ H5T_t *dt_src = NULL; /* Source datatype */
+ H5T_t *dt_dst = NULL; /* Destination datatype */
+ hid_t tid_src = -1; /* Datatype ID for source datatype */
+ hid_t tid_dst = -1; /* Datatype ID for destination datatype */
+ size_t src_dt_size = 0; /* Source datatype size */
+ size_t dst_dt_size = 0; /* Destination datatype size */
+ size_t max_dt_size; /* Max. datatype size */
+ hsize_t nelmts = 0; /* Number of elements in buffer */
+ hssize_t snelmts = 0; /* Number of elements in buffer */
+ size_t request_nelmts; /* requested strip mine */
+ size_t src_nbytes; /* Number of bytes to read from source */
+ size_t dst_nbytes; /* Number of bytes to write to destination */
+ size_t src_start, dst_start;
+ size_t elmts_start;
+ hsize_t total_nbytes; /* Total number of bytes to copy */
+ hsize_t total_src_nbytes; /* Total number of bytes of the source */
+ hsize_t total_dst_nbytes; /* Total number of bytes of the destination */
+ size_t target_size; /* Desired buffer size */
+ void *buf = NULL; /* Buffer for copying data */
+ void *bkg = NULL; /* Temporary buffer for copying data */
+ void *reclaim_buf = NULL; /* Buffer for reclaiming data */
+ H5S_t *buf_space = NULL; /* Dataspace describing buffer */
+ hsize_t buf_dim; /* Dimension for buffer */
+ hbool_t is_vlen = FALSE; /* Flag to indicate VL type */
+ hbool_t vlen_conv = TRUE; /* Transfer property to indicate no conversion for vlen */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_contig_copy_conv, FAIL)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(dset_src && H5D_CONTIGUOUS == dset_src->shared->layout.type);
+ HDassert(dset_dst && H5D_CONTIGUOUS == dset_dst->shared->layout.type);
+
+ /* dataset pointers and IDs */
+ dt_src = dset_src->shared->type;
+ dt_dst = dset_dst->shared->type;
+ tid_src = dset_src->shared->type_id;
+ tid_dst = dset_dst->shared->type_id;
+
+ /* Set up number of bytes to copy, and initial buffer size */
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(dset_src->shared->space)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection")
+ H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,hsize_t);
+
+ if(nelmts==0)
+ HGOTO_DONE(SUCCEED)
+
+ /* Compute element sizes and other parameters */
+ src_dt_size = H5T_get_size(dt_src);
+ dst_dt_size = H5T_get_size(dt_dst);
+ max_dt_size = MAX(src_dt_size, dst_dt_size);
+
+ total_src_nbytes = nelmts*src_dt_size;
+ total_dst_nbytes = nelmts*dst_dt_size;
+ total_nbytes = MAX(total_src_nbytes, total_dst_nbytes);
+ target_size = MIN(H5D_TEMP_BUF_SIZE, (size_t)total_nbytes);
+
+ /* XXX: This could cause a problem if the user sets their buffer size
+ * to the same size as the default, and then the dataset elements are
+ * too large for the buffer... - QAK
+ */
+ if(target_size == H5D_TEMP_BUF_SIZE) {
+ /* If the buffer is too small to hold even one element, make it bigger */
+ if(target_size<max_dt_size)
+ target_size = max_dt_size;
+ /* If the buffer is too large to hold all the elements, make it smaller */
+ else if(target_size>(nelmts*max_dt_size))
+ target_size=(size_t)(nelmts*max_dt_size);
+ } /* end if */
+ request_nelmts = target_size / max_dt_size;
+
+ /* Sanity check elements in temporary buffer */
+ if (request_nelmts==0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small")
+
+ /* If the datatype is or contains vlen, set the property to indicate no conversion
+ * is needed. */
+ if((is_vlen = H5T_detect_class(dt_src, H5T_VLEN)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to detect dtatypes")
+
+ if(is_vlen ) {
+ vlen_conv = FALSE;
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ if(H5P_set(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "Error setting vlen conv flag")
+ }
+
+ /* Set up the conversion functions */
+ if(NULL == (tpath = H5T_path_find(dt_src, dt_dst, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
+
+ /* Set the number of bytes to transfer */
+ src_nbytes = request_nelmts * src_dt_size;
+ dst_nbytes = request_nelmts * dst_dt_size;
+
+ /* Allocate space for copy buffer */
+ HDassert(target_size);
+ if(NULL == (buf = H5FL_BLK_MALLOC(type_conv, target_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer")
+
+ /* allocate temporary bkg buff for data conversion */
+ if(NULL == (bkg = H5FL_BLK_MALLOC(type_conv, target_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer")
+
+ /* Allocate space for destination raw data */
+ if(H5D_contig_create(file, dxpl_id, &(dset_dst->shared->layout)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to allocate contiguous storage")
+
+ /* Loop over copying data */
+ addr_src = dset_src->shared->layout.u.contig.addr;
+ addr_dst = dset_dst->shared->layout.u.contig.addr;
+
+ for (src_start=0, dst_start=0, elmts_start=0; src_start<total_src_nbytes; src_start+=src_nbytes, dst_start+=dst_nbytes, elmts_start+=request_nelmts) {
+ src_nbytes = MIN(src_nbytes, (total_src_nbytes-src_start));
+ dst_nbytes = MIN(dst_nbytes, (total_dst_nbytes-dst_start));
+ request_nelmts = MIN(request_nelmts, (nelmts-elmts_start));
+
+ /* Read raw data from source file */
+ if(H5F_block_read(file, H5FD_MEM_DRAW, addr_src, src_nbytes, H5P_DATASET_XFER_DEFAULT, buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to read raw data")
+
+ /* Set background buffer to all zeros */
+ HDmemset(bkg, 0, target_size);
+
+ /* Convert from memory to destination file */
+ if(H5T_convert(tpath, tid_src, tid_dst, request_nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed")
+
+ /* Write raw data to destination file */
+ if(H5F_block_write(file, H5FD_MEM_DRAW, addr_dst, dst_nbytes, H5P_DATASET_XFER_DEFAULT, buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write raw data")
+
+ /* Adjust loop variables */
+ addr_src += src_nbytes;
+ addr_dst += dst_nbytes;
+ } /* end while */
+
+ /* Set the property of vlen conversion back to normal */
+ if(is_vlen ) {
+ vlen_conv = TRUE;
+
+ if(H5P_set(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "Error setting vlen conv flag")
+ }
+
+done:
+ if(buf)
+ H5FL_BLK_FREE(type_conv, buf);
+ if(reclaim_buf)
+ H5FL_BLK_FREE(type_conv, reclaim_buf);
+ if(bkg)
+ H5FL_BLK_FREE(type_conv, bkg);
+ if(is_vlen && buf_space) {
+ if(H5S_close(buf_space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't free data space")
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_contig_copy_conv() */
diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c
index eaa9057..cad54b5 100644
--- a/src/H5Ddeprec.c
+++ b/src/H5Ddeprec.c
@@ -320,6 +320,7 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
H5S_t *space; /* Dataset's dataspace */
H5O_fill_t *fill; /* Dataset's fill value */
herr_t ret_value = SUCCEED; /* Return value */
+ hid_t fid = -1;
FUNC_ENTER_NOAPI_NOINIT(H5D_extend)
@@ -360,6 +361,10 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
} /* end if */
done:
+ /* Release the file ID */
+ if(fid>=0 && H5I_dec_ref(fid) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't close file ID")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_extend() */
#endif /* H5_NO_DEPRECATED_SYMBOLS */
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 4ee6c19..272b00a 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -60,8 +60,6 @@ typedef struct {
/* General stuff */
static herr_t H5D_init_storage(H5D_t *dataset, hbool_t full_overwrite, hid_t dxpl_id);
static H5D_shared_t *H5D_new(hid_t dcpl_id, hbool_t creating, hbool_t vl_type);
-static herr_t H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id,
- const H5T_t *type);
static herr_t H5D_init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space);
static herr_t H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset);
static herr_t H5D_open_oid(H5D_t *dataset, hid_t dxpl_id);
@@ -447,7 +445,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type)
{
htri_t relocatable; /* Flag whether the type is relocatable */
@@ -829,6 +827,7 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
hbool_t has_vl_type = FALSE; /* Flag to indicate a VL-type for dataset */
hbool_t chunk_init = FALSE; /* Flag to indicate that chunk information was initialized */
H5G_loc_t dset_loc; /* Dataset location */
+ hid_t fid = -1; /* File ID used by filter callbacks */
unsigned u; /* Local index variable */
H5D_t *ret_value; /* Return value */
@@ -887,14 +886,24 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
H5O_pline_t *pline; /* Dataset's I/O pipeline information */
H5O_fill_t *fill; /* Dataset's fill value info */
+ /* Get a file ID for the file */
+ if((fid = H5F_get_id(file)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get file ID")
+
/* Check if the filters in the DCPL can be applied to this dataset */
- if(H5Z_can_apply(new_dset->shared->dcpl_id, new_dset->shared->type_id) < 0)
+ if(H5Z_can_apply(new_dset->shared->dcpl_id, new_dset->shared->type_id, fid) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, NULL, "I/O filters can't operate on this dataset")
/* Make the "set local" filter callbacks for this dataset */
- if(H5Z_set_local(new_dset->shared->dcpl_id, new_dset->shared->type_id) < 0)
+ if(H5Z_set_local(new_dset->shared->dcpl_id, new_dset->shared->type_id, fid) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to set local filter parameters")
+ /* Release the file ID */
+ if(H5I_dec_ref(fid) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEFILE, NULL, "can't close file")
+
+ fid = -1;
+
/* Get new dataset's property list object */
if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(new_dset->shared->dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list")
@@ -1130,6 +1139,10 @@ done:
} /* end if */
new_dset->oloc.file = NULL;
H5FL_FREE(H5D_t, new_dset);
+
+ /* Release the file ID */
+ if(fid>=0 && H5I_dec_ref(fid) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, NULL, "can't close file ID")
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
@@ -1156,6 +1169,7 @@ H5D_open(const H5G_loc_t *loc, hid_t dxpl_id)
{
H5D_shared_t *shared_fo = NULL;
H5D_t *dataset = NULL;
+ hid_t fid = -1; /* File ID for filters */
H5D_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5D_open, NULL)
@@ -1214,6 +1228,27 @@ H5D_open(const H5G_loc_t *loc, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't increment object count")
} /* end else */
+ /* Get a file ID for the file */
+ if((fid = H5F_get_id(dataset->oloc.file)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "unable to get file ID")
+
+ /*
+ * Make the "reset local" filter callbacks for this dataset. It's mainly for some filters
+ * like datatype modification which need some info after the dataset is reopened.
+ * If the library has been closed and reopened, the user-defined filters aren't
+ * registered in the library anymore. This function for those filters can't be
+ * found and may fail. Therefore ignore the error if it's this case.
+ */
+ H5E_BEGIN_TRY {
+ H5Z_reset_local(dataset->shared->dcpl_id, dataset->shared->type_id, fid);
+ } H5E_END_TRY;
+
+ /* Release the file ID */
+ if(H5I_dec_ref(fid) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEFILE, NULL, "can't close file")
+
+ fid = -1;
+
ret_value = dataset;
done:
@@ -1232,6 +1267,10 @@ done:
shared_fo->fo_count--;
} /* end if */
+ /* Release the file ID */
+ if(fid>=0 && H5I_dec_ref(fid) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, NULL, "can't close file ID")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_open() */
@@ -1539,7 +1578,7 @@ H5D_close(H5D_t *dataset)
case H5D_COMPACT:
/* Free the buffer for the raw data for compact datasets */
- dataset->shared->layout.u.compact.buf = H5MM_xfree(dataset->shared->layout.u.compact.buf);
+ dataset->shared->layout.u.compact.buf = H5MM_xfree(dataset->shared->layout.u.compact.buf);
break;
default:
@@ -2205,6 +2244,7 @@ herr_t
H5D_check_filters(H5D_t *dataset)
{
H5O_fill_t *fill; /* Dataset's fill value */
+ hid_t fid = -1; /* File ID used by filter callbacks */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_check_filters)
@@ -2229,16 +2269,30 @@ H5D_check_filters(H5D_t *dataset)
if(fill_status == H5D_FILL_VALUE_DEFAULT || fill_status == H5D_FILL_VALUE_USER_DEFINED) {
if(fill->fill_time == H5D_FILL_TIME_ALLOC ||
(fill->fill_time == H5D_FILL_TIME_IFSET && fill_status == H5D_FILL_VALUE_USER_DEFINED)) {
+ /* Get a file ID for the file */
+ if((fid = H5F_get_id(dataset->oloc.file)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get file ID")
+
/* Filters must have encoding enabled. Ensure that all filters can be applied */
- if(H5Z_can_apply(dataset->shared->dcpl_id, dataset->shared->type_id) < 0)
+ if(H5Z_can_apply(dataset->shared->dcpl_id, dataset->shared->type_id, fid) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "can't apply filters")
dataset->shared->checked_filters = TRUE;
+
+ /* Release the file ID */
+ if(H5I_dec_ref(fid) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEFILE, NULL, "can't close file")
+
+ fid = -1;
} /* end if */
} /* end if */
} /* end if */
done:
+ /* Release the file ID */
+ if(fid>=0 && H5I_dec_ref(fid) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, NULL, "can't close file ID")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_check_filters() */
diff --git a/src/H5Dio.c b/src/H5Dio.c
index bcb90a0..137f161 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -31,6 +31,8 @@
#include "H5MMprivate.h" /* Memory management */
#include "H5Sprivate.h" /* Dataspace functions */
#include "H5SLprivate.h" /* Skip lists */
+#include "H5SMprivate.h" /* Shared Object Header Messages */
+#include "H5Tprivate.h" /* Datatype */
#include "H5Vprivate.h" /* Vector and array functions */
#ifdef H5_HAVE_PARALLEL
@@ -87,6 +89,12 @@ static herr_t H5D_compound_opt_read(size_t nelmts, const H5S_t *mem_space,
void *user_buf/*out*/);
static herr_t H5D_compound_opt_write(size_t nelmts, hid_t src_id, hid_t dst_id,
void *data_buf);
+static herr_t H5D_modify_dtype_with_filter(H5F_t *file, H5D_t *dataset,
+ hid_t type_id, H5T_t *type, hid_t dxpl_id);
+static herr_t H5D_modify_dtype_without_filter(H5F_t *file, H5D_t *dataset,
+ hid_t type_id, H5T_t *type, hid_t dxpl_id);
+static herr_t H5D_modify_dtype_update_fill(H5F_t *file, H5D_t *dataset, struct H5O_t *oh,
+ hid_t dxpl_id);
#ifdef H5_HAVE_PARALLEL
static herr_t H5D_ioinfo_term(H5D_io_info_t *io_info);
@@ -614,6 +622,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
#endif /*H5_HAVE_PARALLEL*/
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
H5D_dxpl_cache_t *dxpl_cache=&_dxpl_cache; /* Data transfer property cache */
+ hid_t fid = -1; /* File ID for filters */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_write)
@@ -627,9 +636,19 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
/* All filters in the DCPL must have encoding enabled. */
if(!dataset->shared->checked_filters) {
- if(H5Z_can_apply(dataset->shared->dcpl_id, dataset->shared->type_id) <0)
+ /* Get a file ID for the file */
+ if((fid = H5F_get_id(dataset->oloc.file)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get file ID")
+
+ if(H5Z_can_apply(dataset->shared->dcpl_id, dataset->shared->type_id, fid) <0)
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "can't apply filters")
+ /* Release the file ID */
+ if(H5I_dec_ref(fid) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEFILE, FAIL, "can't close file")
+
+ fid = -1;
+
dataset->shared->checked_filters = TRUE;
} /* end if */
@@ -763,6 +782,10 @@ done:
HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "can't shut down io_info")
#endif /*H5_HAVE_PARALLEL*/
+ /* Release the file ID */
+ if(fid>=0 && H5I_dec_ref(fid) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't close file ID")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_write() */
@@ -1369,7 +1392,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, hsize_t nelmts,
void *chunk = NULL;
haddr_t chunk_addr; /* Chunk address on disk */
H5D_istore_ud1_t udata; /*B-tree pass-through */
- unsigned idx_hint=0; /* Cache index hint */
+ unsigned idx_hint = 0; /* Cache index hint */
herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_read)
@@ -1761,7 +1784,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, hsize_t nelmts,
void *chunk = NULL;
haddr_t chunk_addr; /* Chunk address on disk */
H5D_istore_ud1_t udata; /*B-tree pass-through */
- unsigned idx_hint=0; /* Cache index hint */
+ unsigned idx_hint = 0; /* Cache index hint */
hbool_t relax=TRUE; /* Whether whole chunk is selected */
herr_t ret_value = SUCCEED; /*return value */
@@ -2333,6 +2356,563 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Dmodify_dtype
+ *
+ * Purpose: Modifies the data type of the dataset and converts the data
+ * according to the new data type. If the dataset is chunked
+ * and the creation property is set through
+ * H5Pset_dtype_modifiable, the conversion of the data only
+ * happens when the chunks are accessed during either reading
+ * or writing. This design will save the time from converting
+ * unused data. If the dataset is chunked but the creation
+ * property is NOT set through H5Pset_dtype_modifiable, the
+ * data is converted immediately after this function is called.
+ * If the dataset is contiguous or compact, the data is also
+ * converted immediately.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * Tuesday, 25 Sept. 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dmodify_dtype(hid_t dset_id, hid_t new_type_id)
+{
+
+ H5D_t *dset = NULL;
+ H5T_t *new_type = NULL;
+ herr_t ret_value;
+
+ FUNC_ENTER_API(H5Dmodify_dtype, FAIL)
+ H5TRACE2("e", "ii", dset_id, new_type_id);
+
+ /* Check args */
+ if(NULL==(dset=(H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+
+ if(NULL==(new_type=(H5T_t *)H5I_object_verify(new_type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+
+ /* Check if we are allowed to write to this file */
+ if(0==(H5F_get_intent(dset->oloc.file) & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "no write intent on file")
+
+ /* If the new type is the same as the current, simply finish it */
+ if(0 == H5T_cmp(dset->shared->type, new_type, FALSE))
+ HGOTO_DONE(SUCCEED)
+ /*HGOTO_ERROR(H5E_DATASET, H5E_CANTMODIFY, FAIL, "new datatype is the same as the datatype of the dataset")*/
+
+ /* Check if the datatype is valid for this operation */
+ if(TRUE != H5T_dtype_is_valid(dset->shared->type, new_type))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "datatype is not valid")
+
+ /* Modify the data type */
+ if(H5D_modify_dtype(dset->oloc.file, dset, new_type_id, new_type, H5AC_dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't modify datatype")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_modify_dtype
+ *
+ * Purpose: Private function for H5Dmodify_dtype. It handles the
+ * dataset differently depending on the situation.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * Tuesday, 25 Sept. 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_modify_dtype(H5F_t *file, H5D_t *dataset, hid_t type_id, H5T_t *type, hid_t dxpl_id)
+{
+ hbool_t filter_enabled = FALSE; /* Flag for the datatype modification filter */
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_modify_dtype, FAIL)
+
+ /* check args */
+ HDassert(file);
+ HDassert(dataset);
+ HDassert(type);
+
+ /* Check if the dataset has a non-default DCPL & check the filter if so */
+ if(dataset->shared->dcpl_id != H5P_DATASET_CREATE_DEFAULT
+ && H5D_CHUNKED == dataset->shared->layout.type) {
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(dataset->shared->dcpl_id, H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_DATASET, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ H5E_BEGIN_TRY {
+ /*ret = H5Pget_filter_by_id(dataset->shared->dcpl_id, H5Z_FILTER_DTYPE_MODIFY, NULL, NULL, NULL, (size_t)0, NULL, NULL);*/
+ ret = H5P_get_filter_by_id(plist, H5Z_FILTER_DTYPE_MODIFY, NULL, NULL, NULL, (size_t)0, NULL, NULL);
+ } H5E_END_TRY;
+
+ if(ret >= 0)
+ filter_enabled = TRUE;
+ } /* end if */
+
+ if(filter_enabled) {
+ /* For chunked dataset when the filter of datatype modification is enabled */
+ if(H5D_modify_dtype_with_filter(file, dataset, type_id, type, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't modify datatype")
+ } else {
+ /* For chunked dataset when the filter is NOT enabled or for contiguous or
+ * compact dataset */
+ if(H5D_modify_dtype_without_filter(file, dataset, type_id, type, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't modify datatype")
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_modify_dtype() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_modify_dtype_without_filter
+ *
+ * Purpose: For chunked dataset with the filter of dtype modification
+ * disabled or contiguous or compact dataset, this function
+ * modifies the data type of the dataset and converts the
+ * data according to the new data type.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * Tuesday, 25 Sept. 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_modify_dtype_without_filter(H5F_t *file, H5D_t *dataset, hid_t type_id, H5T_t *type,
+ hid_t dxpl_id)
+{
+ H5D_t *new_dset;
+ H5O_fill_t *fill_prop; /* Fill value property */
+ H5O_copy_t cp_info;
+ struct H5O_t *oh = NULL; /* Pointer to dataset's object header */
+ hbool_t has_data = TRUE; /* The flag to indicate data exists in dset */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_modify_dtype_without_filter, FAIL)
+
+ /* If space hasn't been allocated and not using external storage,
+ * set the flag HAS_DATA to FALSE. If the dataset is compact,
+ * the flag is always TRUE.
+ */
+ if(dataset->shared->dcpl_cache.efl.nused == 0 &&
+ ((dataset->shared->layout.type == H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr))
+ || (dataset->shared->layout.type == H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr))))
+ has_data = FALSE;
+
+ if(has_data) {
+ /*
+ * Create a bogus dataset with the same properties as the current one, to read,
+ * convert the data, and write it in this bogus dataset. Then assign the ownership
+ * of this data to the current dataset. The metadata of this bogus will be
+ * deleted as it's closed.
+ */
+ if(NULL == (new_dset = H5D_create(file, type_id, dataset->shared->space, dataset->shared->dcpl_id, dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "unable to create a new dset")
+
+ /* Copy and convert the data piece by piece in case that the dataset is too big
+ * for the memory.
+ */
+ switch(dataset->shared->layout.type) {
+ case H5D_COMPACT:
+ if(H5D_compact_copy_conv(dataset, new_dset, &cp_info, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+
+ break;
+ case H5D_CONTIGUOUS:
+ if(H5D_contig_copy_conv(file, dataset, new_dset, &cp_info, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+
+ /* Flush the raw data buffer, if we have a dirty one */
+ if(dataset->shared->cache.contig.sieve_buf && dataset->shared->cache.contig.sieve_dirty) {
+ /* Write dirty data sieve buffer to file */
+ if(H5F_block_write(file, H5FD_MEM_DRAW, dataset->shared->cache.contig.sieve_loc,
+ dataset->shared->cache.contig.sieve_size, dxpl_id, dataset->shared->cache.contig.sieve_buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
+
+ /* Reset sieve buffer dirty flag */
+ dataset->shared->cache.contig.sieve_dirty = FALSE;
+ } /* end if */
+
+ break;
+ case H5D_CHUNKED:
+ if(H5D_istore_copy_conv(file, dataset, new_dset, &cp_info, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
+
+ H5D_istore_flush(new_dset, dxpl_id, H5F_FLUSH_INVALIDATE);
+
+ break;
+ default:
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "dataset should be contiguous or chunked")
+ }
+ }
+
+ /* Copy & initialize datatype for the dataset struct */
+ if(H5D_init_type(file, dataset, type_id, type) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't copy datatype")
+
+ /* Check if the datatype should be (or are already) shared in the SOHM table */
+ if(H5SM_try_share(file, dxpl_id, NULL, H5O_DTYPE_ID, dataset->shared->type, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADMESG, FAIL, "trying to share datatype failed")
+
+ /*
+ * Check whether datatype is committed & increment ref count. (to maintain
+ * ref. count incr/decr similarity with "shared message" type of datatype sharing)
+ */
+ if(H5T_committed(dataset->shared->type)) {
+ /* Increment the reference count on the shared datatype */
+ if(H5T_link(dataset->shared->type, 1, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
+ } /* end if */
+
+ /* Open the object header of the original dataset for updating datatype and layout */
+ if(H5O_open(&(dataset->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open dataset object header")
+
+ /* Get a pointer to the object header itself */
+ if((oh = H5O_protect(&(dataset->oloc), dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to protect dataset object header")
+
+ /* Delete the old datatype message */
+ if(H5O_msg_remove(&(dataset->oloc), H5O_DTYPE_ID, 0, FALSE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete old dtype message")
+
+ /* Add the new datatype message */
+ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT, 0, dataset->shared->type) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update datatype header message")
+
+ /* Delete the old layout message. If it's contiguous dataset, link the adjacent space. */
+ if(H5O_msg_remove(&(dataset->oloc), H5O_LAYOUT_ID, 0, TRUE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete old dtype message")
+
+ if(has_data) {
+ /* Assign the ownership of the new data to the original dataset */
+ if(H5D_CONTIGUOUS == dataset->shared->layout.type) {
+ dataset->shared->layout.u.contig.addr = new_dset->shared->layout.u.contig.addr;
+ dataset->shared->layout.u.contig.size = new_dset->shared->layout.u.contig.size;
+ } else if (H5D_COMPACT == dataset->shared->layout.type) {
+ H5MM_free(dataset->shared->layout.u.compact.buf);
+
+ dataset->shared->layout.u.compact.buf = new_dset->shared->layout.u.compact.buf;
+ dataset->shared->layout.u.compact.size = new_dset->shared->layout.u.compact.size;
+ } else {
+ dataset->shared->layout.u.chunk.addr = new_dset->shared->layout.u.chunk.addr;
+ dataset->shared->layout.u.chunk.size = new_dset->shared->layout.u.chunk.size;
+ }
+ }
+
+ /*
+ * Create a new layout message. (Don't make layout message constant unless
+ * allocation time is early, since space may not be allocated)
+ */
+ fill_prop = &(dataset->shared->dcpl_cache.fill);
+ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_LAYOUT_ID, ((fill_prop->alloc_time == H5D_ALLOC_TIME_EARLY && H5D_COMPACT != dataset->shared->layout.type) ? H5O_MSG_FLAG_CONSTANT : 0), 0, &(dataset->shared->layout)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout")
+
+ /*
+ * Create a new fill value message if it's defined.
+ */
+ if(H5D_modify_dtype_update_fill(file, dataset, oh, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update fill value message")
+
+ /* Add a modification time message. */
+ if(H5O_touch_oh(file, dxpl_id, oh, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time message")
+
+ /* Release pointer to object header itself */
+ if(H5O_unprotect(&(dataset->oloc), oh) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header")
+
+ /* Close the object header for the dataset */
+ if(H5O_close(&(dataset->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close dataset object header")
+
+ if(has_data) {
+ /* Update and delete the object header of the new dataset */
+ if(H5O_open(&(new_dset->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open dataset object header")
+
+ /* Get a pointer to the object header itself */
+ if((oh = H5O_protect(&(new_dset->oloc), dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to protect dataset object header")
+
+ /* Disconnect the new data from the bogus dataset by updating the layout */
+ if(H5O_msg_remove(&(new_dset->oloc), H5O_LAYOUT_ID, 0, FALSE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete old dtype message")
+
+ if(H5D_CONTIGUOUS == new_dset->shared->layout.type) {
+ new_dset->shared->layout.u.contig.addr = HADDR_UNDEF;
+ new_dset->shared->layout.u.contig.size = 0;
+ } else if (H5D_COMPACT == new_dset->shared->layout.type) {
+ new_dset->shared->layout.u.compact.buf = NULL;
+ new_dset->shared->layout.u.compact.size = 0;
+ } else {
+ new_dset->shared->layout.u.chunk.addr = HADDR_UNDEF;
+ new_dset->shared->layout.u.chunk.size = 0;
+ }
+
+ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_LAYOUT_ID, /*H5O_MSG_FLAG_CONSTANT*/ 0, 0, &(new_dset->shared->layout)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout")
+
+ /* Release pointer to object header itself */
+ if(H5O_unprotect(&(new_dset->oloc), oh) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header")
+
+ if(H5O_close(&(new_dset->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release object header")
+
+ /* Close the bogus dataset. It'll be removed, too, because it's unnamed. */
+ if(H5D_close(new_dset) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close dataset")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_modify_dtype_without_filter() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_modify_dtype_with_filter
+ *
+ * Purpose: For chunked dataset with the filter of dtype modification
+ * enabled. It only modifies the data type of the dataset.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * Tuesday, 25 Sept. 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_modify_dtype_with_filter(H5F_t *file, H5D_t *dataset, hid_t type_id, H5T_t *type,
+ hid_t dxpl_id)
+{
+ hid_t fid = -1; /* File ID for filters */
+ H5O_fill_t *fill;
+ struct H5O_t *oh = NULL; /* Pointer to dataset's object header */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_modify_dtype_with_filter, FAIL)
+
+ /* Get a file ID for the file */
+ if((fid = H5F_get_id(file)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get file ID")
+
+ /* Copy & initialize datatype for the dataset struct */
+ if(H5D_init_type(file, dataset, type_id, type) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't copy datatype")
+
+ /* Check if the datatype should be (or are already) shared in the SOHM table */
+ if(H5SM_try_share(file, dxpl_id, NULL, H5O_DTYPE_ID, dataset->shared->type, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADMESG, FAIL, "trying to share datatype failed")
+
+ /*
+ * Check whether datatype is committed & increment ref count. (to maintain
+ * ref. count incr/decr similarity with "shared message" type of datatype sharing)
+ */
+ if(H5T_committed(dataset->shared->type)) {
+ /* Increment the reference count on the shared datatype */
+ if(H5T_link(dataset->shared->type, 1, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
+ } /* end if */
+
+ /* Update the layout info */
+ dataset->shared->layout.u.chunk.dim[dataset->shared->layout.u.chunk.ndims-1] = H5T_get_size(dataset->shared->type);
+
+ /* Compute the new total size of chunk */
+ for(u = 1, dataset->shared->layout.u.chunk.size = dataset->shared->layout.u.chunk.dim[0]; u < dataset->shared->layout.u.chunk.ndims; u++)
+ dataset->shared->layout.u.chunk.size *= dataset->shared->layout.u.chunk.dim[u];
+
+ /* Open the object header of the dataset for updating datatype and layout */
+ if(H5O_open(&(dataset->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to open dataset object header")
+
+ /* Get a pointer to the object header itself */
+ if((oh = H5O_protect(&(dataset->oloc), dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to protect dataset object header")
+
+ /* Delete the old datatype message */
+ if(H5O_msg_remove(&(dataset->oloc), H5O_DTYPE_ID, 0, FALSE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete old dtype message")
+
+ /* Add the new datatype message */
+ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT, 0, dataset->shared->type) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update datatype header message")
+
+ /* Delete the old layout message */
+ if(H5O_msg_remove(&(dataset->oloc), H5O_LAYOUT_ID, 0, FALSE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete old dtype message")
+
+ /*
+ * Create a new layout message. (Don't make layout message constant unless
+ * allocation time is early, since space may not be allocated)
+ */
+ fill = &(dataset->shared->dcpl_cache.fill);
+ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_LAYOUT_ID, ((fill->alloc_time == H5D_ALLOC_TIME_EARLY && H5D_COMPACT != dataset->shared->layout.type) ? H5O_MSG_FLAG_CONSTANT : 0), 0, &(dataset->shared->layout)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout")
+
+ /*
+ * Create a new fill value message if it's defined.
+ */
+/* if(H5D_modify_dtype_update_fill(file, dataset, oh, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update fill value message")*/
+
+ /* Add a modification time message. */
+ if(H5O_touch_oh(file, dxpl_id, oh, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time message")
+
+ /* Release pointer to object header itself */
+ if(H5O_unprotect(&(dataset->oloc), oh) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header")
+
+ /* Close the object header for the dataset */
+ if(H5O_close(&(dataset->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close dataset object header")
+
+ /* Make the "reset local" filter callbacks for this dataset */
+ if(H5Z_reset_local(dataset->shared->dcpl_id, dataset->shared->type_id, fid) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set local filter parameters")
+
+ /* Release the file ID */
+ if(H5I_dec_ref(fid) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEFILE, FAIL, "can't close file")
+
+ fid = -1;
+
+done:
+ /* Release the file ID */
+ if(fid>=0 && H5I_dec_ref(fid) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't close file ID")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_modify_dtype_with_filter() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_modify_dtype_update_fill
+ *
+ * Purpose: A private function to facilitate H5D_modify_dtype_with_filter
+ * and H5D_modify_dtype_without_filter to update the header
+ * message for fill value.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * Tuesday, 20 Nov. 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_modify_dtype_update_fill(H5F_t *file, H5D_t *dataset, struct H5O_t *oh,
+ hid_t dxpl_id)
+{
+ H5O_fill_t *fill_prop; /* Fill value property */
+ H5D_fill_value_t fill_status; /* Fill value status */
+ hbool_t fill_changed = FALSE; /* Flag indicating the fill value was changed */
+ hbool_t use_latest_format; /* Flag indicating the newest file format should be used */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_modify_dtype_update_fill, FAIL)
+
+ fill_prop = &(dataset->shared->dcpl_cache.fill);
+
+ /*
+ * Create a new fill value message if it's defined.
+ */
+ /* Retrieve "defined" status of fill value */
+ if(H5P_is_fill_value_defined(fill_prop, &fill_status) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined")
+
+ /* Determine whether fill value is defined or not */
+ if(fill_status == H5D_FILL_VALUE_DEFAULT || fill_status == H5D_FILL_VALUE_USER_DEFINED) {
+ /* Convert fill value buffer to dataset's new datatype */
+ if(fill_prop->buf && fill_prop->size > 0 && H5O_fill_convert(fill_prop, dataset->shared->type, &fill_changed, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to convert fill value to new type")
+
+ fill_prop->fill_defined = TRUE;
+ } else if(fill_status == H5D_FILL_VALUE_UNDEFINED) {
+ fill_prop->fill_defined = FALSE;
+ } else
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to determine if fill value is defined")
+
+ if(fill_changed) {
+ H5P_genplist_t *dc_plist; /* Dataset's creation property list */
+
+ /* Get dataset's property list object */
+ HDassert(dataset->shared->dcpl_id != H5P_DATASET_CREATE_DEFAULT);
+ if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(dataset->shared->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
+
+ /* Update dataset creation property */
+ if(H5P_set(dc_plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value info")
+ } /* end if */
+
+ /* Delete the old fill value message */
+ if(H5O_msg_remove(&(dataset->oloc), H5O_FILL_NEW_ID, 0, FALSE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete old fill value message")
+
+ /* Write new fill value message */
+ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_FILL_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, fill_prop) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update new fill value header message")
+
+ /* Get the file's 'use the latest version of the format' flag */
+ use_latest_format = H5F_USE_LATEST_FORMAT(file);
+
+ /* If there is valid information for the old fill value struct, add it */
+ /* (only if we aren't trying to write the latest version of the file format) */
+ if(fill_prop->buf && !use_latest_format) {
+ H5O_fill_t old_fill_prop; /* Copy of fill value property, for writing as "old" fill value */
+
+ /* Shallow copy the fill value property */
+ /* (we only want to make certain that the shared component isnt' modified) */
+ HDmemcpy(&old_fill_prop, fill_prop, sizeof(old_fill_prop));
+
+ /* Reset shared component info */
+ H5O_msg_reset_share(H5O_FILL_ID, &old_fill_prop);
+
+ /* Delete the old fill value message */
+ if(H5O_msg_remove(&(dataset->oloc), H5O_FILL_ID, 0, FALSE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete old fill value message")
+
+ /* Write old fill value */
+ if(H5O_msg_append_oh(file, dxpl_id, oh, H5O_FILL_ID, H5O_MSG_FLAG_CONSTANT, 0, &old_fill_prop) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update old fill value header message")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_modify_dtype_update_fill() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_create_chunk_map
*
* Purpose: Creates the mapping between elements selected in each chunk
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 47e4cab..1b7fca0 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -174,6 +174,7 @@ typedef struct H5D_istore_it_ud4_t {
hid_t tid_dst; /* Datatype ID for destination datatype */
hid_t tid_mem; /* Datatype ID for memory datatype */
H5T_t *dt_src; /* Source datatype */
+ H5T_t *dt_dst; /* Destination datatype */
H5T_path_t *tpath_src_mem; /* Datatype conversion path from source file to memory */
H5T_path_t *tpath_mem_dst; /* Datatype conversion path from memory to dest. file */
void *reclaim_buf; /* Buffer for reclaiming data */
@@ -229,6 +230,8 @@ static int H5D_istore_prune_check(H5F_t *f, hid_t dxpl_id, const void *_lt_key,
const void *_rt_key, void *_udata);
static int H5D_istore_iter_copy(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
const void *_rt_key, void *_udata);
+static int H5D_istore_iter_copy_conv(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
+ const void *_rt_key, void *_udata);
/* B-tree callbacks */
static H5RC_t *H5D_istore_get_shared(const H5F_t *f, const void *_udata);
@@ -965,6 +968,7 @@ H5D_istore_iter_dump (H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_lt_key
* Programmer: Peter Cao
* August 20, 2005
*
+ * Modification:
*-------------------------------------------------------------------------
*/
static int
@@ -1123,6 +1127,145 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_istore_iter_copy_conv
+ *
+ * Purpose: copy chunked raw data from source file and insert to the
+ * B-tree node in the destination file. The data conversion
+ * is for H5D_istore_copy_conv that is used by H5Dmodify_dtype.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 8 October 2007
+ *
+ * Modification:
+ *-------------------------------------------------------------------------
+ */
+static int
+H5D_istore_iter_copy_conv(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key,
+ haddr_t addr_src, const void UNUSED *_rt_key, void *_udata)
+{
+ H5D_istore_it_ud4_t *udata = (H5D_istore_it_ud4_t *)_udata;
+ const H5D_istore_key_t *lt_key = (const H5D_istore_key_t *)_lt_key;
+ H5D_istore_ud1_t udata_dst; /* User data about new destination chunk */
+ hbool_t is_vlen = FALSE;
+ hbool_t fix_ref = FALSE;
+ hbool_t other_conversion = FALSE;
+
+ /* General information about chunk copy */
+ void *bkg = udata->bkg;
+ void *buf = udata->buf;
+ size_t buf_size = udata->buf_size;
+ H5O_pline_t *pline = udata->pline;
+
+ /* needed for commpressed variable length data */
+ hbool_t is_compressed = FALSE;
+ H5Z_EDC_t edc_read = H5Z_NO_EDC;
+ size_t nbytes = lt_key->nbytes;
+ size_t src_nbytes, dst_nbytes;
+ H5Z_cb_t cb_struct;
+
+ H5T_path_t *tpath = udata->tpath_src_mem;
+ H5S_t *buf_space = udata->buf_space;
+ hid_t tid_src = udata->tid_src;
+ hid_t tid_dst = udata->tid_dst;
+ size_t nelmts = udata->nelmts;
+
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_istore_iter_copy_conv)
+
+ /* Check parameter for type conversion */
+ if(H5T_detect_class(udata->dt_src, H5T_VLEN) > 0)
+ is_vlen = TRUE;
+
+ /* Check for filtered chunks */
+ if(pline && pline->nused) {
+ is_compressed = TRUE;
+ cb_struct.func = NULL; /* no callback function when failed */
+ } /* end if */
+
+ /* Resize the buf if it is too small to hold the data */
+ if(nbytes > buf_size) {
+ void *new_buf; /* New buffer for data */
+
+ /* Re-allocate memory for copying the chunk */
+ if(NULL == (new_buf = H5MM_realloc(udata->buf, nbytes)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for raw data chunk")
+ udata->buf = new_buf;
+ if(udata->bkg) {
+ if(NULL == (new_buf = H5MM_realloc(udata->bkg, nbytes)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for raw data chunk")
+ udata->bkg = new_buf;
+ if(!udata->cpy_info->expand_ref)
+ HDmemset((uint8_t *)udata->bkg + buf_size, 0, (size_t)(nbytes - buf_size));
+
+ bkg = udata->bkg;
+ } /* end if */
+
+ buf = udata->buf;
+ udata->buf_size = buf_size = nbytes;
+ } /* end if */
+
+ /* read chunk data from the source file. Make sure to use
+ * the source size. */
+ src_nbytes = udata->nelmts * H5T_get_size(udata->dt_src);
+ if(H5F_block_read(f_src, H5FD_MEM_DRAW, addr_src, src_nbytes, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, H5_ITER_ERROR, "unable to read raw data chunk")
+
+ /* Need to uncompress data elements */
+ if(is_compressed) {
+ unsigned filter_mask = lt_key->filter_mask;
+
+ if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &filter_mask, edc_read, cb_struct, &src_nbytes, &buf_size, &buf) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, H5_ITER_ERROR, "data pipeline read failed")
+ } /* end if */
+
+ /* Set background buffer to all zeros */
+ HDmemset(bkg, 0, buf_size);
+
+ /* Convert from memory to destination file */
+ if(H5T_convert(tpath, tid_src, tid_dst, nelmts, (size_t)0, (size_t)0, buf, bkg, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "datatype conversion failed")
+
+ /* Copy source chunk callback information for insertion */
+ HDmemset(&udata_dst, 0, sizeof(udata_dst));
+ /*HDmemcpy(&(udata_dst.common.key), lt_key, sizeof(H5D_istore_key_t));*/
+
+ udata_dst.common.mesg = udata->common.mesg; /* Share this pointer for a short while */
+ udata_dst.common.offset = lt_key->offset;
+ dst_nbytes = udata->nelmts * H5T_get_size(udata->dt_dst);
+ udata_dst.nbytes = dst_nbytes;
+ udata_dst.filter_mask = lt_key->filter_mask;
+ udata_dst.addr = HADDR_UNDEF;
+
+ /* Need to compress variable-length & reference data elements before writing to file */
+ if(is_compressed) {
+ if(H5Z_pipeline(pline, 0, &(udata_dst.filter_mask), edc_read,
+ cb_struct, &dst_nbytes, &buf_size, &buf) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, H5_ITER_ERROR, "output pipeline failed")
+ udata->buf = buf;
+ udata->buf_size = buf_size;
+ }
+
+ /* Insert chunk into the destination Btree */
+ if(H5B_insert(udata->file_dst, dxpl_id, H5B_ISTORE, udata->addr_dst, &udata_dst) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, H5_ITER_ERROR, "unable to allocate chunk")
+
+ /* Write chunk data to destination file */
+ HDassert(H5F_addr_defined(udata_dst.addr));
+
+ /* For H5D_istore_copy_conv that is used by H5Dmodify_dtype. Make sure to use
+ * the destination size. */
+ if(H5F_block_write(udata->file_dst, H5FD_MEM_DRAW, udata_dst.addr, dst_nbytes, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, H5_ITER_ERROR, "unable to write raw data to file")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_istore_iter_copy() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_istore_cinfo_cache_reset
*
* Purpose: Reset the cached chunk info
@@ -1814,7 +1957,7 @@ H5D_istore_lock(const H5D_io_info_t *io_info, H5D_istore_ud1_t *udata,
hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache*/
H5D_rdcc_ent_t *ent = NULL; /*cache entry */
- unsigned idx = 0; /*hash index number */
+ unsigned idx = UINT_MAX; /*hash index number */
hbool_t found = FALSE; /*already in cache? */
size_t chunk_size; /*size of a chunk */
void *chunk = NULL; /*the file chunk */
@@ -3785,6 +3928,13 @@ done:
* Programmer: Peter Cao
* August 20, 2005
*
+ * Modification:
+ * Raymond Lu
+ * 8 October 2007
+ * Originally the function set up type conversion information
+ * if there's a VLEN source datatype. But for the case of no
+ * conversion, still initialize these variables for the now
+ * more generalized H5D_istore_iter_copy.
*-------------------------------------------------------------------------
*/
herr_t
@@ -3804,6 +3954,12 @@ H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
H5S_t *buf_space = NULL; /* Dataspace describing buffer */
hid_t sid_buf = -1; /* ID for buffer dataspace */
size_t nelmts = 0; /* Number of elements in buffer */
+ H5T_t *dt_dst; /* Destination datatype */
+ H5T_t *dt_mem; /* Memory datatype */
+ size_t mem_dt_size; /* Memory datatype size */
+ size_t tmp_dt_size; /* Temp. datatype size */
+ size_t max_dt_size; /* Max atatype size */
+ unsigned u;
hbool_t do_convert = FALSE; /* Indicate that type conversions should be performed */
herr_t ret_value = SUCCEED; /* Return value */
@@ -3833,51 +3989,49 @@ H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize chunked storage")
} /* end if */
- /* If there's a VLEN source datatype, set up type conversion information */
+ /*
+ * Set up type conversion information if there's a VLEN source datatype. But for the
+ * case of no conversion, still initialize these variables for the now more generalized
+ * H5D_istore_iter_copy.
+ */
+
+ /* create a memory copy of the variable-length datatype */
+ if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
+ if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
+
+ /* create variable-length datatype at the destinaton file */
+ if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
+ if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
+ if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype")
+
+ /* Set up the conversion functions */
+ if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
+ if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes")
+
+ /* Determine largest datatype size */
+ if(0 == (max_dt_size = H5T_get_size(dt_src)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
+ if(0 == (mem_dt_size = H5T_get_size(dt_mem)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
+ max_dt_size = MAX(max_dt_size, mem_dt_size);
+ if(0 == (tmp_dt_size = H5T_get_size(dt_dst)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
+ max_dt_size = MAX(max_dt_size, tmp_dt_size);
+
+ /* Compute the number of elements per chunk */
+ nelmts = 1;
+ for(u = 0; u < (layout_src->u.chunk.ndims - 1); u++)
+ nelmts *= layout_src->u.chunk.dim[u];
+
if(H5T_detect_class(dt_src, H5T_VLEN) > 0) {
- H5T_t *dt_dst; /* Destination datatype */
- H5T_t *dt_mem; /* Memory datatype */
- size_t mem_dt_size; /* Memory datatype size */
- size_t tmp_dt_size; /* Temp. datatype size */
- size_t max_dt_size; /* Max atatype size */
hsize_t buf_dim; /* Dimension for buffer */
- unsigned u;
-
- /* create a memory copy of the variable-length datatype */
- if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
- if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype")
-
- /* create variable-length datatype at the destinaton file */
- if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy")
- if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
- if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype")
-
- /* Set up the conversion functions */
- if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem, NULL, NULL, dxpl_id, FALSE)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
- if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst, NULL, NULL, dxpl_id, FALSE)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes")
-
- /* Determine largest datatype size */
- if(0 == (max_dt_size = H5T_get_size(dt_src)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
- if(0 == (mem_dt_size = H5T_get_size(dt_mem)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
- max_dt_size = MAX(max_dt_size, mem_dt_size);
- if(0 == (tmp_dt_size = H5T_get_size(dt_dst)))
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size")
- max_dt_size = MAX(max_dt_size, tmp_dt_size);
-
- /* Compute the number of elements per chunk */
- nelmts = 1;
- for(u = 0; u < (layout_src->u.chunk.ndims - 1); u++)
- nelmts *= layout_src->u.chunk.dim[u];
-
/* Create the space and set the initial extent */
buf_dim = nelmts;
if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL)))
@@ -3939,6 +4093,7 @@ H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src, H5F_t *f_dst,
udata.tid_mem = tid_mem;
udata.tid_dst = tid_dst;
udata.dt_src = dt_src;
+ udata.dt_dst = dt_src;
udata.do_convert = do_convert;
udata.tpath_src_mem = tpath_src_mem;
udata.tpath_mem_dst = tpath_mem_dst;
@@ -3989,6 +4144,162 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_istore_copy_conv
+ *
+ * Purpose: Copies an indexed storage B-tree from SRC file to DST file
+ * and does data conversion. This function is similar to
+ * H5D_istore_copy and is mainly used by H5Dmodify_dtype.
+ *
+ * Return: Non-negative on success (with the ISTORE argument initialized
+ * and ready to write to an object header). Negative on failure.
+ *
+ * Programmer: Raymond Lu
+ * 8 October 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_istore_copy_conv(H5F_t *file, const H5D_t *dset_src, const H5D_t *dset_dst,
+ H5O_copy_t UNUSED *cpy_info, hid_t dxpl_id)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5D_istore_it_ud4_t udata;
+ H5T_path_t *tpath = NULL; /* Datatype conversion paths */
+ H5T_t *dt_src = NULL; /* Source datatype */
+ H5T_t *dt_dst = NULL; /* Destination datatype */
+ hid_t tid_src = -1; /* Datatype ID for source datatype */
+ hid_t tid_dst = -1; /* Datatype ID for destination datatype */
+ size_t src_dt_size = 0; /* Source datatype size */
+ size_t dst_dt_size = 0; /* Destination datatype size */
+ size_t max_dt_size; /* Max. datatype size */
+ hsize_t nelmts = 0; /* Number of elements in buffer */
+ size_t buf_size; /* Size of copy buffer */
+ void *buf = NULL; /* Buffer for copying data */
+ void *bkg = NULL; /* Buffer for background during type conversion */
+ H5S_t *buf_space = NULL; /* Dataspace describing buffer */
+ hsize_t buf_dim; /* Dimension for buffer */
+ hbool_t is_vlen = FALSE; /* Flag to indicate VL type */
+ hbool_t vlen_conv = TRUE; /* Transfer property to indicate no conversion for vlen */
+ unsigned u;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_istore_copy_conv, FAIL)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(dset_src && H5D_CHUNKED == dset_src->shared->layout.type);
+ HDassert(dset_dst && H5D_CHUNKED == dset_dst->shared->layout.type);
+
+ dt_src = dset_src->shared->type;
+ dt_dst = dset_dst->shared->type;
+ tid_src = dset_src->shared->type_id;
+ tid_dst = dset_dst->shared->type_id;
+
+ /* Compute the number of elements per chunk */
+ nelmts = 1;
+ for(u = 0; u < (dset_src->shared->layout.u.chunk.ndims - 1); u++)
+ nelmts *= dset_src->shared->layout.u.chunk.dim[u];
+
+ /* Compute element sizes and other parameters */
+ src_dt_size = H5T_get_size(dt_src);
+ dst_dt_size = H5T_get_size(dt_dst);
+ max_dt_size = MAX(src_dt_size, dst_dt_size);
+
+ /* Check if we need to create the B-tree in the dest. file */
+ if(dset_dst->shared->layout.u.chunk.addr == HADDR_UNDEF) {
+ /* Create the root of the B-tree that describes chunked storage */
+ if(H5D_istore_create(file, dxpl_id, &(dset_dst->shared->layout)) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize chunked storage")
+ } /* end if */
+
+ /* If the datatype is or contains vlen, set the property to indicate no conversion
+ * is needed. */
+ if((is_vlen = H5T_detect_class(dt_src, H5T_VLEN)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to detect dtatypes")
+
+ if(is_vlen ) {
+ vlen_conv = FALSE;
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ if(H5P_set(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "Error setting vlen conv flag")
+ /*if(H5P_get(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "Error getting vlen conv flag")*/
+ }
+
+ /* Set up the conversion functions */
+ if(NULL == (tpath = H5T_path_find(dt_src, dt_dst, NULL, NULL, dxpl_id, FALSE)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes")
+
+ /* Create the space and set the initial extent */
+ buf_dim = nelmts;
+ if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
+
+ /* Set initial buffer sizes */
+ buf_size = nelmts * max_dt_size;
+
+ /* Allocate background memory for converting the chunk */
+ if(NULL == (bkg = H5MM_malloc(buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for raw data chunk")
+
+ HDmemset(bkg, 0, buf_size);
+
+ /* Allocate memory for copying the chunk */
+ if(NULL == (buf = H5MM_malloc(buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for raw data chunk")
+
+ /* Initialize the callback structure for the source */
+ HDmemset(&udata, 0, sizeof udata);
+ udata.common.mesg = &(dset_src->shared->layout);
+ udata.file_src = file;
+ udata.addr_dst = dset_dst->shared->layout.u.chunk.addr;
+ udata.buf = buf;
+ udata.bkg = bkg;
+ udata.buf_size = buf_size;
+ udata.tid_src = tid_src;
+ udata.tid_dst = tid_dst;
+ udata.dt_src = dt_src;
+ udata.dt_dst = dt_dst;
+ udata.do_convert = TRUE;
+ udata.tpath_src_mem = tpath;
+ udata.buf_space = buf_space;
+ udata.nelmts = nelmts;
+ udata.pline = &(dset_src->shared->dcpl_cache.pline);
+ udata.file_dst = file;
+ udata.cpy_info = cpy_info;
+
+ /* copy the chunked data by iteration */
+ if(H5B_iterate(file, dxpl_id, H5B_ISTORE, H5D_istore_iter_copy_conv, dset_src->shared->layout.u.chunk.addr, &udata) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to iterate over chunk B-tree")
+
+ /* I/O buffers may have been re-allocated */
+ buf = udata.buf;
+ bkg = udata.bkg;
+
+ /* Set the property of vlen conversion back to normal */
+ if(is_vlen ) {
+ vlen_conv = TRUE;
+
+ if(H5P_set(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "Error setting vlen conv flag")
+ }
+
+done:
+ if(buf)
+ H5MM_xfree(buf);
+ if(bkg)
+ H5MM_xfree(bkg);
+
+ if(buf_space && H5S_close(buf_space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't free data space")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_istore_copy_conv() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_istore_bh_size
*
* Purpose: Retrieve the amount of B-tree storage for chunked dataset
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index aec5e19..300fb18 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -361,6 +361,8 @@ H5_DLL herr_t H5D_vlen_get_buf_size(void *elem, hid_t type_id, unsigned ndim,
const hsize_t *point, void *op_data);
H5_DLL herr_t H5D_check_filters(H5D_t *dataset);
H5_DLL herr_t H5D_set_extent(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id);
+H5_DLL herr_t H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id,
+ const H5T_t *type);
/* Functions that perform serial I/O operations */
H5_DLL herr_t H5D_select_fscat(H5D_io_info_t *io_info,
@@ -398,6 +400,8 @@ H5_DLL ssize_t H5D_contig_writevv(const H5D_io_info_t *io_info,
haddr_t UNUSED address, void UNUSED *pointer, const void *buf);
H5_DLL herr_t H5D_contig_copy(H5F_t *f_src, const H5O_layout_t *layout_src, H5F_t *f_dst,
H5O_layout_t *layout_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id);
+H5_DLL herr_t H5D_contig_copy_conv(H5F_t *file, const H5D_t *dset_src, const H5D_t *dset_dst,
+ H5O_copy_t UNUSED *cpy_info, hid_t dxpl_id);
/* Functions that operate on compact dataset storage */
H5_DLL herr_t H5D_compact_fill(H5D_t *dset, hid_t dxpl_id);
@@ -411,6 +415,8 @@ H5_DLL ssize_t H5D_compact_writevv(const H5D_io_info_t *io_info,
haddr_t UNUSED addr, void UNUSED *pointer/*in*/, const void *buf);
H5_DLL herr_t H5D_compact_copy(H5F_t *f_src, H5O_layout_t *layout_src,
H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype, H5O_copy_t *cpy_info, hid_t dxpl_id);
+H5_DLL herr_t H5D_compact_copy_conv(const H5D_t *dset_src, const H5D_t *dset_dst,
+ H5O_copy_t UNUSED *cpy_info, hid_t dxpl_id);
/* Functions that operate on indexed storage */
/* forward reference for collective-chunk IO use */
@@ -448,6 +454,8 @@ H5_DLL haddr_t H5D_istore_get_addr(const H5D_io_info_t *io_info,
H5_DLL herr_t H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src,
H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype,
H5O_copy_t *cpy_info, H5O_pline_t *pline, hid_t dxpl_id);
+H5_DLL herr_t H5D_istore_copy_conv(H5F_t *file, const H5D_t *dset_src, const H5D_t *dset_dst,
+ H5O_copy_t UNUSED *cpy_info, hid_t dxpl_id);
H5_DLL void * H5D_istore_lock(const H5D_io_info_t *io_info, H5D_istore_ud1_t *udata,
hbool_t relax, unsigned *idx_hint/*in,out*/);
H5_DLL herr_t H5D_istore_unlock(const H5D_io_info_t *io_info,
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index 410dc43..c5192b2 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -60,6 +60,7 @@
#define H5D_XFER_VLEN_ALLOC_INFO_NAME "vlen_alloc_info" /* Vlen allocation info */
#define H5D_XFER_VLEN_FREE_NAME "vlen_free" /* Vlen free function */
#define H5D_XFER_VLEN_FREE_INFO_NAME "vlen_free_info" /* Vlen free info */
+#define H5D_XFER_VLEN_CONV_NAME "vlen_conv" /* whether vlen conversion is needed */
#define H5D_XFER_VFL_ID_NAME "vfl_id" /* File driver ID */
#define H5D_XFER_VFL_INFO_NAME "vfl_info" /* File driver info */
#define H5D_XFER_HYPER_VECTOR_SIZE_NAME "vec_size" /* Hyperslab vector size */
@@ -165,6 +166,11 @@ H5_DLL H5T_t *H5D_typeof(const H5D_t *dset);
H5_DLL herr_t H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags);
H5_DLL herr_t H5D_get_dxpl_cache(hid_t dxpl_id, H5D_dxpl_cache_t **cache);
H5_DLL herr_t H5D_get_dxpl_cache_real(hid_t dxpl_id, H5D_dxpl_cache_t *cache);
+/*H5_DLL herr_t H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id,
+ const H5T_t *type);
+H5_DLL hsize_t H5D_get_storage_size(H5D_t *dset, hid_t dxpl_id);*/
+H5_DLL herr_t H5D_modify_dtype(H5F_t *file, H5D_t *dataset, hid_t type_id, H5T_t *type,
+ hid_t dxpl_id);
/* Functions that operate on vlen data */
H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id,
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index d7f6574..3cbfadd 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -114,6 +114,7 @@ H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_
H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf,
hid_t buf_type, hid_t space);
H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t *size);
+H5_DLL herr_t H5Dmodify_dtype(hid_t dset_id, hid_t new_type_id);
H5_DLL herr_t H5Ddebug(hid_t dset_id);
/* Symbols defined for compatibility with previous versions of the HDF5 API.
diff --git a/src/H5Gbtree2.c b/src/H5Gbtree2.c
index 2e2f215..a2ef892 100644
--- a/src/H5Gbtree2.c
+++ b/src/H5Gbtree2.c
@@ -164,7 +164,7 @@ H5G_dense_fh_name_cmp(const void *obj, size_t UNUSED obj_len, void *_udata)
FUNC_ENTER_NOAPI_NOINIT(H5G_dense_fh_name_cmp)
/* Decode link information */
- if(NULL == (lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj, H5O_MSG_FLAG_WAS_UNKNOWN)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
/* Compare the string values */
diff --git a/src/H5Gdense.c b/src/H5Gdense.c
index ed53a47..8028466 100644
--- a/src/H5Gdense.c
+++ b/src/H5Gdense.c
@@ -566,7 +566,7 @@ H5G_dense_lookup_by_idx_fh_cb(const void *obj, size_t UNUSED obj_len, void *_uda
FUNC_ENTER_NOAPI_NOINIT(H5G_dense_lookup_by_idx_fh_cb)
/* Decode link information & keep a copy */
- if(NULL == (tmp_lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (tmp_lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj, H5O_MSG_FLAG_WAS_UNKNOWN)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
/* Copy link information */
@@ -852,7 +852,7 @@ H5G_dense_iterate_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
* HDF5 routine, it could attempt to re-protect that direct block for the
* heap, causing the HDF5 routine called to fail - QAK)
*/
- if(NULL == (udata->lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (udata->lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj, H5O_MSG_FLAG_WAS_UNKNOWN)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
done:
@@ -1047,7 +1047,7 @@ H5G_dense_get_name_by_idx_fh_cb(const void *obj, size_t UNUSED obj_len, void *_u
FUNC_ENTER_NOAPI_NOINIT(H5G_dense_get_name_by_idx_fh_cb)
/* Decode link information */
- if(NULL == (lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj, H5O_MSG_FLAG_WAS_UNKNOWN)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
/* Get the length of the name */
@@ -1245,7 +1245,7 @@ H5G_dense_remove_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
FUNC_ENTER_NOAPI_NOINIT(H5G_dense_remove_fh_cb)
/* Decode link information */
- if(NULL == (lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj, H5O_MSG_FLAG_WAS_UNKNOWN)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode link")
/* Check for removing the link from the creation order index */
@@ -1408,7 +1408,7 @@ H5G_dense_remove_by_idx_fh_cb(const void *obj, size_t UNUSED obj_len, void *_uda
FUNC_ENTER_NOAPI_NOINIT(H5G_dense_remove_by_idx_fh_cb)
/* Decode link information */
- if(NULL == (udata->lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj)))
+ if(NULL == (udata->lnk = H5O_msg_decode(udata->f, udata->dxpl_id, H5O_LINK_ID, obj, H5O_MSG_FLAG_WAS_UNKNOWN)))
HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, H5_ITER_ERROR, "can't decode link")
/* Can't operate on link here because the fractal heap block is locked */
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index 23bc28e..7454d76 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -384,7 +384,7 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr);
UINT32DECODE(p, hdr->pline_root_direct_filter_mask);
/* Decode I/O filter information */
- if(NULL == (pline = (H5O_pline_t *)H5O_msg_decode(hdr->f, dxpl_id, H5O_PLINE_ID, p)))
+ if(NULL == (pline = (H5O_pline_t *)H5O_msg_decode(hdr->f, dxpl_id, H5O_PLINE_ID, p, H5O_MSG_FLAG_WAS_UNKNOWN)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, NULL, "can't decode I/O pipeline filters")
p += hdr->filter_len;
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index e750d48..79e448c 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -354,12 +354,16 @@ H5O_layout_copy(const void *_mesg, void *_dest)
/* Deep copy the buffer for compact datasets also */
if(mesg->type == H5D_COMPACT) {
- /* Allocate memory for the raw data */
- if(NULL == (dest->u.compact.buf = H5MM_malloc(dest->u.compact.size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset")
-
- /* Copy over the raw data */
- HDmemcpy(dest->u.compact.buf, mesg->u.compact.buf, dest->u.compact.size);
+ if(dest->u.compact.size) {
+ /* Allocate memory for the raw data */
+ if(NULL == (dest->u.compact.buf = H5MM_malloc(dest->u.compact.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset")
+
+ /* Copy over the raw data */
+ HDmemcpy(dest->u.compact.buf, mesg->u.compact.buf, dest->u.compact.size);
+ } else {
+ dest->u.compact.buf = NULL;
+ }
} /* end if */
/* Set return value */
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index 3130066..3c4e3dd 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -480,9 +480,11 @@ H5O_msg_read(const H5O_loc_t *loc, unsigned type_id, void *mesg,
/* check args */
HDassert(loc);
HDassert(loc->file);
- HDassert(H5F_addr_defined(loc->addr));
HDassert(type_id < NELMTS(H5O_msg_class_g));
+ if(!H5F_addr_defined(loc->addr))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "address isn't defined")
+
/* Get the object header */
if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header")
@@ -1807,7 +1809,8 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5O_msg_decode(H5F_t *f, hid_t dxpl_id, unsigned type_id, const unsigned char *buf)
+H5O_msg_decode(H5F_t *f, hid_t dxpl_id, unsigned type_id, const unsigned char *buf,
+ unsigned mesg_flag)
{
const H5O_msg_class_t *type; /* Actual H5O class type for the ID */
void *ret_value; /* Return value */
@@ -1821,7 +1824,7 @@ H5O_msg_decode(H5F_t *f, hid_t dxpl_id, unsigned type_id, const unsigned char *b
HDassert(type);
/* decode */
- if((ret_value = (type->decode)(f, dxpl_id, 0, buf)) == NULL)
+ if((ret_value = (type->decode)(f, dxpl_id, mesg_flag, buf)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode message")
done:
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 72d9e2d..bdecc73 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -594,7 +594,7 @@ H5_DLL herr_t H5O_msg_get_crt_index(unsigned type_id, const void *mesg,
H5_DLL herr_t H5O_msg_encode(H5F_t *f, unsigned type_id, hbool_t disable_shared,
unsigned char *buf, const void *obj);
H5_DLL void* H5O_msg_decode(H5F_t *f, hid_t dxpl_id, unsigned type_id,
- const unsigned char *buf);
+ const unsigned char *buf, unsigned mesg_flag);
H5_DLL herr_t H5O_msg_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
unsigned type_id, void *mesg);
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index e406065..c1569e3 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -323,7 +323,9 @@ H5O_shared_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *buf, const H5O_msg_cla
* Otherwise, it is a named datatype, so copy an H5O_loc_t.
*/
if(sh_mesg.type == H5O_SHARE_TYPE_SOHM) {
- HDassert(version >= H5O_SHARED_VERSION_3);
+ if(version < H5O_SHARED_VERSION_3)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for shared object message")
+
HDmemcpy(&sh_mesg.u.heap_id, buf, sizeof(sh_mesg.u.heap_id));
} /* end if */
else {
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index 8d6b9ab..fa92315 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -75,7 +75,6 @@
#define H5D_CRT_DATA_PIPELINE_DEF {{0, NULL, H5O_NULL_ID, {{0, HADDR_UNDEF}}}, H5O_PLINE_VERSION_1, 0, 0, NULL}
#define H5D_CRT_DATA_PIPELINE_CMP H5P_dcrt_data_pipeline_cmp
-
/******************/
/* Local Typedefs */
/******************/
@@ -2028,7 +2027,7 @@ H5Pset_fletcher32(hid_t plist_id)
if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
if(H5Z_append(&pline, H5Z_FILTER_FLETCHER32, H5Z_FLAG_MANDATORY, (size_t)0, NULL) < 0)
- HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add deflate filter to pipeline")
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add fletcher32 filter to pipeline")
if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline")
@@ -2038,6 +2037,57 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Pset_dtype_modifiable
+ *
+ * Purpose: Sets the property to enable the modification of the
+ * dataset's datatype for a dataset creation property list.
+ * After the function H5Dmodify_dtype is called,
+ * if the dataset is chunked, the conversion of the data only
+ * happens when the chunks are accessed during either reading
+ * or writing. This design will save the time from converting
+ * unused data. If the dataset is contiguous or compact,
+ * the data is converted immediately. This property has no
+ * effect for the contiguous and compact datasets.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Aug 27, 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_dtype_modifiable(hid_t plist_id)
+{
+ H5O_pline_t pline;
+ H5P_genplist_t *plist; /* Property list pointer */
+ size_t cd_nelmts=3; /* Number of filter parameters */
+ unsigned cd_values[3]={0,0}; /* Filter parameters */
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Pset_dtype_modifiable, FAIL)
+ H5TRACE1("e", "i", plist_id);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Add the datatype modification as a filter */
+ if(H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get pipeline")
+ if(H5Z_append(&pline, H5Z_FILTER_DTYPE_MODIFY, H5Z_FLAG_MANDATORY, cd_nelmts, cd_values) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to add dtype modify filter to pipeline")
+ if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to set pipeline")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_dtype_modifiable() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Pset_fill_value
*
* Purpose: Set the fill value for a dataset creation property list. The
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c
index 6affcad..de04150 100644
--- a/src/H5Pdxpl.c
+++ b/src/H5Pdxpl.c
@@ -75,6 +75,9 @@
/* Definitions for vlen free info property */
#define H5D_XFER_VLEN_FREE_INFO_SIZE sizeof(void *)
#define H5D_XFER_VLEN_FREE_INFO_DEF H5D_VLEN_FREE_INFO
+/* Definitions for data conversion of vlen type */
+#define H5D_XFER_VLEN_CONV_SIZE sizeof(hbool_t)
+#define H5D_XFER_VLEN_CONV_DEF TRUE
/* Definitions for file driver ID property */
#define H5D_XFER_VFL_ID_SIZE sizeof(hid_t)
#define H5D_XFER_VFL_ID_DEF H5FD_VFD_DEFAULT
@@ -194,6 +197,7 @@ H5P_dxfr_reg_prop(H5P_genclass_t *pclass)
void *def_vlen_alloc_info = H5D_XFER_VLEN_ALLOC_INFO_DEF; /* Default value for vlen allocation information */
H5MM_free_t def_vlen_free = H5D_XFER_VLEN_FREE_DEF; /* Default value for vlen free function */
void *def_vlen_free_info = H5D_XFER_VLEN_FREE_INFO_DEF; /* Default value for vlen free information */
+ void *def_vlen_conv = H5D_XFER_VLEN_CONV_DEF; /* Default value for vlen free information */
hid_t def_vfl_id = H5D_XFER_VFL_ID_DEF; /* Default value for file driver ID */
void *def_vfl_info = H5D_XFER_VFL_INFO_DEF; /* Default value for file driver info */
size_t def_hyp_vec_size = H5D_XFER_HYPER_VECTOR_SIZE_DEF; /* Default value for vector size */
@@ -249,6 +253,10 @@ H5P_dxfr_reg_prop(H5P_genclass_t *pclass)
if(H5P_register(pclass, H5D_XFER_VLEN_FREE_INFO_NAME, H5D_XFER_VLEN_FREE_INFO_SIZE, &def_vlen_free_info, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the vlen free information property */
+ if(H5P_register(pclass, H5D_XFER_VLEN_CONV_NAME, H5D_XFER_VLEN_CONV_SIZE, &def_vlen_conv, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
/* Register the file driver ID property */
if(H5P_register(pclass, H5D_XFER_VFL_ID_NAME, H5D_XFER_VFL_ID_SIZE, &def_vfl_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index f1e98af..c64a878 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -304,6 +304,7 @@ H5_DLL herr_t H5Pset_shuffle(hid_t plist_id);
H5_DLL herr_t H5Pset_nbit(hid_t plist_id);
H5_DLL herr_t H5Pset_scaleoffset(hid_t plist_id, H5Z_SO_scale_type_t scale_type, int scale_factor);
H5_DLL herr_t H5Pset_fletcher32(hid_t plist_id);
+H5_DLL herr_t H5Pset_dtype_modifiable(hid_t plist_id);
H5_DLL herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id,
const void *value);
H5_DLL herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id,
diff --git a/src/H5S.c b/src/H5S.c
index 8a58cba..5b1495d 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -1807,7 +1807,7 @@ H5S_decode(const unsigned char *buf)
/* Decode the extent part of dataspace */
/* (pass mostly bogus file pointer and bogus DXPL) */
- if((extent = (H5S_extent_t *)H5O_msg_decode(f, H5P_DEFAULT, H5O_SDSPACE_ID, buf))==NULL)
+ if((extent = (H5S_extent_t *)H5O_msg_decode(f, H5P_DEFAULT, H5O_SDSPACE_ID, buf, H5O_MSG_FLAG_WAS_UNKNOWN))==NULL)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDECODE, NULL, "can't decode object")
buf += extent_size;
diff --git a/src/H5SM.c b/src/H5SM.c
index 179a526..9fb946c 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -1398,7 +1398,7 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg)
* master table needs to be unprotected when we do this.
*/
if(mesg_buf) {
- if(NULL == (native_mesg = H5O_msg_decode(f, dxpl_id, type_id, (const unsigned char *)mesg_buf)))
+ if(NULL == (native_mesg = H5O_msg_decode(f, dxpl_id, type_id, (const unsigned char *)mesg_buf, H5O_MSG_FLAG_WAS_UNKNOWN)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "can't decode shared message.")
if(H5O_msg_delete(f, dxpl_id, open_oh, type_id, native_mesg) < 0)
diff --git a/src/H5T.c b/src/H5T.c
index 04d6c0b..ae96807 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -265,6 +265,7 @@ static herr_t H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src,
static herr_t H5T_register(H5T_pers_t pers, const char *name, H5T_t *src,
H5T_t *dst, H5T_conv_t func, hid_t dxpl_id, hbool_t api_call);
static htri_t H5T_compiler_conv(H5T_t *src, H5T_t *dst);
+static htri_t H5T_path_is_noop(const H5T_t *src_type, const H5T_t *dst_type, hid_t dxpl_id);
static herr_t H5T_encode(H5T_t *obj, unsigned char *buf, size_t *nalloc);
static H5T_t *H5T_decode(const unsigned char *buf);
@@ -2931,7 +2932,7 @@ H5T_decode(const unsigned char *buf)
HGOTO_ERROR(H5E_DATATYPE, H5E_VERSION, NULL, "unknown version of encoded datatype")
/* Decode the serialized datatype message */
- if((ret_value = H5O_msg_decode(f, H5AC_dxpl_id, H5O_DTYPE_ID, buf)) == NULL)
+ if((ret_value = H5O_msg_decode(f, H5AC_dxpl_id, H5O_DTYPE_ID, buf, H5O_MSG_FLAG_WAS_UNKNOWN)) == NULL)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL, "can't decode object")
done:
@@ -4207,6 +4208,76 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5T_path_is_noop
+ *
+ * Purpose: Private function for H5T_path_find to decide whether a
+ * conversion path exists between the source and destination
+ * types.
+ *
+ * Return: TRUE: no conversion.
+ * FALSE: has conversion
+ * FAIL: function failed.
+ *
+ * Programmer: Raymond Lu
+ * 24 October 2007
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5T_path_is_noop(const H5T_t *src_type, const H5T_t *dst_type, hid_t dxpl_id)
+{
+ H5T_class_t src_class, dst_class;
+ H5P_genplist_t *plist; /* Property list pointer */
+ htri_t ret_value = FALSE;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5T_path_is_noop)
+
+ if((src_class = H5T_get_class(src_type, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to get type class");
+
+ if((dst_class = H5T_get_class(dst_type, FALSE)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to get type class");
+
+#ifdef TMP
+ if(H5T_VLEN == src_class && H5T_VLEN == dst_class &&
+ H5T_LOC_DISK == src_type->shared->u.vlen.loc &&
+ H5T_LOC_DISK == dst_type->shared->u.vlen.loc &&
+ 0==H5T_cmp(src_type, dst_type, TRUE))
+ ret_value = TRUE;
+#else
+ /* If the library indicates that no conversion through transfer property,
+ * don't convert. This case is primarily for the filter of modifying
+ * dataset's datatype.
+ */
+ if(H5T_VLEN == src_class && H5T_VLEN == dst_class) {
+ hbool_t vlen_conv;
+
+ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ if(H5P_get(plist, H5D_XFER_VLEN_CONV_NAME, &vlen_conv) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "Error getting vlen conv flag")
+
+ if(!vlen_conv)
+ ret_value = TRUE;
+ }
+#endif
+
+ /* Quincey Koziol, 2 July, 1999
+ * Allow the no-op conversion to occur if no "force conversion" flags are set
+ */
+ if(src_type->shared->force_conv==FALSE && dst_type->shared->force_conv==FALSE
+ && 0==H5T_cmp(src_type, dst_type, TRUE))
+ ret_value = TRUE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /*H5T_path_is_noop*/
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_path_find
*
* Purpose: Finds the path which converts type SRC_ID to type DST_ID,
@@ -4257,7 +4328,8 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
hid_t src_id=-1, dst_id=-1; /*src and dst type identifiers */
int i; /*counter */
int nprint=0; /*lines of output printed */
-
+ htri_t is_noop = FALSE; /*flag for noop */
+
FUNC_ENTER_NOAPI(H5T_path_find, NULL);
assert((!src && !dst) || (src && dst));
@@ -4292,12 +4364,11 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name,
* Find the conversion path. If source and destination types are equal
* then use entry[0], otherwise do a binary search over the
* remaining entries.
- *
- * Quincey Koziol, 2 July, 1999
- * Only allow the no-op conversion to occur if no "force conversion" flags
- * are set
*/
- if (src->shared->force_conv==FALSE && dst->shared->force_conv==FALSE && 0==H5T_cmp(src, dst, TRUE)) {
+ if((is_noop = H5T_path_is_noop(src, dst, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to find noop condition");
+
+ if(is_noop) {
table = H5T_g.path[0];
cmp = 0;
md = 0;
@@ -5220,3 +5291,329 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_set_latest_version() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_dtype_is_valid
+ *
+ * Purpose: Private function to facilitate H5Dmodify_dtype. It
+ * verifies whether the new type is valid.
+ *
+ * Return: TRUE: Positive
+ *
+ * FALSE: Zero
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * Tuesday, 25 Sept. 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5T_dtype_is_valid(H5T_t *dtype, H5T_t *new_type)
+{
+ H5T_class_t cur_class, new_class;
+ htri_t ret_value = TRUE;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5T_dtype_is_valid)
+
+ /* Check if the datatype is "sensible" for use in a dataset */
+ if(H5T_is_sensible(new_type) != TRUE)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "datatype is not sensible")
+
+ cur_class = H5T_get_class(dtype, FALSE);
+ new_class = H5T_get_class(new_type, FALSE);
+
+ switch(cur_class) {
+ case H5T_INTEGER:
+ {
+ size_t dtype_prec;
+
+ if(new_class != H5T_INTEGER && new_class != H5T_FLOAT)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be integer or float number")
+
+ if((dtype_prec = H5T_get_precision(dtype)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get integer precision")
+
+ /* Verify if the new type is a valid integer */
+ if(H5T_INTEGER == new_class) {
+ size_t new_type_prec;
+ H5T_sign_t new_type_sign, dtype_sign;
+
+ if((new_type_prec = H5T_get_precision(new_type)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get integer precision")
+
+ if((new_type_sign = H5T_get_sign(new_type)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get integer sign")
+
+ if((dtype_sign = H5T_get_sign(dtype)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get integer sign")
+
+ if(H5T_SGN_2 == dtype_sign && H5T_SGN_NONE == new_type_sign)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "can't change signed integer to unsigned")
+
+ if((new_type_prec - (dtype_sign != new_type_sign) < dtype_prec))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "can't change to a smaller integer")
+
+ } else if(H5T_FLOAT == new_class) {
+ size_t new_msize;
+
+ if (H5T_get_fields(new_type, NULL, NULL, NULL, NULL, &new_msize) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get fields")
+
+ if (new_msize < dtype_prec)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "can't change a float with smaller precision")
+ }
+ }
+ break;
+ case H5T_FLOAT:
+ {
+ size_t cur_esize, cur_msize;
+
+ if(new_class != H5T_INTEGER && new_class != H5T_FLOAT)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be integer or float number")
+
+ if (H5T_get_fields(dtype, NULL, NULL, &cur_esize, NULL, &cur_msize) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get fields")
+
+ if(H5T_INTEGER == new_class) {
+ size_t new_type_prec;
+ H5T_sign_t new_type_sign;
+
+ if((new_type_sign = H5T_get_sign(new_type)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get integer sign")
+
+ if(H5T_SGN_NONE == new_type_sign)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "can't change to an unsigned integer")
+
+ if((new_type_prec = H5T_get_precision(new_type)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get integer precision")
+
+ if(new_type_prec < cur_msize)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type has smaller precision")
+
+ } else if(H5T_FLOAT == new_class) {
+ size_t new_esize, new_msize;
+
+ if (H5T_get_fields(new_type, NULL, NULL, &new_esize, NULL, &new_msize) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get fields")
+
+ if (new_msize < cur_msize || new_esize < cur_esize)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type has smaller mantissa or exponent")
+
+ }
+ }
+ break;
+ case H5T_STRING:
+ if(new_class != H5T_STRING)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be a string type")
+
+ if((TRUE != H5T_is_variable_str(dtype)) && (TRUE != H5T_is_variable_str(new_type))) {
+ size_t dtype_size, new_size;
+
+ if((dtype_size = H5T_get_size(dtype)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get string size")
+
+ if((new_size = H5T_get_size(new_type)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get string size")
+
+ if(new_size < dtype_size)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type has smaller size")
+ }
+
+ if(H5T_is_variable_str(dtype) != H5T_is_variable_str(new_type))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "can't change from/to a VL string")
+
+ break;
+ case H5T_BITFIELD:
+ {
+ size_t dtype_prec, new_type_prec;
+
+ if(new_class != H5T_BITFIELD)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be a bitfield type")
+
+ if((dtype_prec = H5T_get_precision(dtype)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get bitfield precision")
+
+ if((new_type_prec = H5T_get_precision(new_type)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get bitfield precision")
+
+ if(new_type_prec < dtype_prec)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new bitfield has smaller precision")
+ }
+
+ break;
+ case H5T_OPAQUE:
+ {
+ size_t dtype_size, new_type_size;
+
+ if(new_class != H5T_OPAQUE)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be an opaque type")
+
+ if((dtype_size = H5T_get_size(dtype)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get opaque size")
+
+ if((new_type_size = H5T_get_size(new_type)) == 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get opaque size")
+
+ if(new_type_size < dtype_size)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new opaque has smaller size")
+ }
+
+ break;
+ case H5T_COMPOUND:
+ {
+ int dtype_nmembs, new_type_nmembs;
+ int *src2dst = NULL;
+ int i, j;
+
+ if(new_class != H5T_COMPOUND)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be a compound type")
+
+ if((dtype_nmembs = H5T_get_nmembers(dtype)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get number of members")
+
+ if((new_type_nmembs = H5T_get_nmembers(new_type)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get number of members")
+
+ if(new_type_nmembs < dtype_nmembs)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "no compound field should be deleted")
+
+ H5T_sort_name(dtype, NULL);
+ H5T_sort_name(new_type, NULL);
+
+ /*
+ * Build a mapping from source member number to destination member
+ * number. If some source member is not a destination member then that
+ * mapping element will be negative. Also verify if each member is valid.
+ */
+ src2dst=H5MM_malloc(dtype_nmembs * sizeof(int));
+
+ for (i=0; i<dtype_nmembs; i++) {
+ src2dst[i] = -1;
+ for (j=0; j<new_type_nmembs; j++) {
+ if (!HDstrcmp(dtype->shared->u.compnd.memb[i].name,
+ new_type->shared->u.compnd.memb[j].name)) {
+ src2dst[i] = j;
+ break;
+ }
+ }
+
+ if(src2dst[i] < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "no compound field should be deleted")
+ else {
+ if(TRUE != H5T_dtype_is_valid(dtype->shared->u.compnd.memb[i].type,
+ new_type->shared->u.compnd.memb[src2dst[i]].type))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new compound field isn't valid")
+ }
+ }
+ }
+ break;
+ case H5T_REFERENCE:
+ if(new_class != H5T_REFERENCE)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be a compound type")
+
+ break;
+ case H5T_ENUM:
+ {
+ int cur_nmemb, new_nmemb;
+
+ if(new_class != H5T_ENUM)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be an enum type")
+
+ if((cur_nmemb = H5T_get_nmembers(dtype)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get number of members")
+
+ if((new_nmemb = H5T_get_nmembers(new_type)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get number of members")
+
+ if(new_nmemb < cur_nmemb)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new enum's members can't be less than current enum")
+ }
+
+ break;
+ case H5T_VLEN:
+ {
+ H5T_t *cur_base, *new_base;
+
+ if(new_class != H5T_VLEN)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be a vlen type")
+
+ if((cur_base = H5T_get_super(dtype)) == NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get the base type")
+
+ if((new_base = H5T_get_super(new_type)) == NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get the base type")
+
+ if(H5T_cmp(cur_base, new_base, FALSE))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "the base type of VL type can't be changed")
+
+ if(H5T_close(cur_base) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "can't close the base type")
+
+ if(H5T_close(new_base) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "can't close the base type")
+ }
+ break;
+ case H5T_ARRAY:
+ {
+ H5T_t *cur_base, *new_base;
+ int cur_ndims, new_ndims;
+ hsize_t *cur_dims, *new_dims;
+ int i;
+
+ if(new_class != H5T_ARRAY)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "new type must be an array type")
+
+ if((cur_base = H5T_get_super(dtype)) == NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get the base type")
+
+ if((new_base = H5T_get_super(new_type)) == NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "can't get the base type")
+
+ if(TRUE != H5T_dtype_is_valid(cur_base, new_base))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "the base type of the new type isn't valid")
+ if(H5T_close(cur_base) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "can't close the base type")
+
+ if(H5T_close(new_base) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "can't close the base type")
+
+ if((cur_ndims = H5T_get_array_ndims(dtype)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get number of dimension")
+
+ if((new_ndims = H5T_get_array_ndims(new_type)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get number of dimensions")
+
+ if(new_ndims != cur_ndims)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "the number of dimensions can't be changed")
+
+ HDassert(cur_ndims);
+ cur_dims = (hsize_t*)H5MM_malloc(cur_ndims*sizeof(hsize_t));
+ new_dims = (hsize_t*)H5MM_malloc(new_ndims*sizeof(hsize_t));
+
+ if(H5T_get_array_dims(dtype, cur_dims) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get dimension info")
+
+ if(H5T_get_array_dims(new_type, new_dims) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get dimension info")
+
+ for(i=0; i<cur_ndims; i++) {
+ if(new_dims[i] != cur_dims[i])
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "the dimension can't be changed")
+ }
+
+ if(cur_dims)
+ H5MM_free(cur_dims);
+ if(new_dims)
+ H5MM_free(new_dims);
+ }
+
+ break;
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FALSE, "current type isn't recognizable")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
diff --git a/src/H5Tcompound.c b/src/H5Tcompound.c
index 660a76d..27425bd 100644
--- a/src/H5Tcompound.c
+++ b/src/H5Tcompound.c
@@ -27,6 +27,7 @@
#include "H5private.h" /*generic functions */
#include "H5Eprivate.h" /*error handling */
#include "H5Iprivate.h" /*ID functions */
+#include "H5Dprivate.h" /*dataset */
#include "H5MMprivate.h" /*memory management */
#include "H5Tpkg.h" /*data-type functions */
@@ -614,4 +615,3 @@ H5T_is_packed(const H5T_t *dt)
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_is_packed() */
-
diff --git a/src/H5Tfloat.c b/src/H5Tfloat.c
index 73ccf30..63a7f24 100644
--- a/src/H5Tfloat.c
+++ b/src/H5Tfloat.c
@@ -94,6 +94,48 @@ H5Tget_fields(hid_t type_id, size_t *spos/*out*/,
if (H5T_FLOAT != dt->shared->type)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "operation not defined for datatype class")
+ if (H5T_get_fields(dt, spos, epos, esize, mpos, msize) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't get fields")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_get_fields
+ *
+ * Purpose: Returns information about the locations of the various bit
+ * fields of a floating point datatype. The field positions
+ * are bit positions in the significant region of the datatype.
+ * Bits are numbered with the least significant bit number zero.
+ *
+ * Any (or even all) of the arguments can be null pointers.
+ *
+ * Return: Success: Non-negative, field locations and sizes are
+ * returned through the arguments.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, January 7, 1998
+ *
+ * Modifications:
+ * Robb Matzke, 22 Dec 1998
+ * Also works with derived datatypes.
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5T_get_fields(H5T_t *dt, size_t *spos/*out*/,
+ size_t *epos/*out*/, size_t *esize/*out*/,
+ size_t *mpos/*out*/, size_t *msize/*out*/)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5T_get_fields, FAIL)
+
+ HDassert(dt);
+
/* Get values */
if (spos) *spos = dt->shared->u.atomic.u.f.sign;
if (epos) *epos = dt->shared->u.atomic.u.f.epos;
@@ -102,7 +144,7 @@ H5Tget_fields(hid_t type_id, size_t *spos/*out*/,
if (msize) *msize = dt->shared->u.atomic.u.f.msize;
done:
- FUNC_LEAVE_API(ret_value)
+ FUNC_LEAVE_NOAPI(ret_value)
}
diff --git a/src/H5Tprecis.c b/src/H5Tprecis.c
index 62493e9..194e746 100644
--- a/src/H5Tprecis.c
+++ b/src/H5Tprecis.c
@@ -75,6 +75,8 @@ H5T_init_precis_interface(void)
* Robb Matzke, 22 Dec 1998
* Also works for derived datatypes.
*
+ * Raymond Lu, 26 Sept 2007
+ * Split a private function from this API function.
*-------------------------------------------------------------------------
*/
size_t
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index dfe2367..c102ead 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -116,8 +116,14 @@ H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc);
H5_DLL htri_t H5T_is_sensible(const H5T_t *dt);
H5_DLL uint32_t H5T_hash(H5F_t * file, const H5T_t *dt);
H5_DLL herr_t H5T_set_latest_version(H5T_t *dt);
+H5_DLL htri_t H5T_dtype_is_valid(H5T_t *dtype, H5T_t *new_type);
H5_DLL htri_t H5T_is_variable_str(const H5T_t *dt);
+/* Flowing-point type */
+H5_DLL herr_t H5T_get_fields(H5T_t *dt, size_t *spos/*out*/,
+ size_t *epos/*out*/, size_t *esize/*out*/,
+ size_t *mpos/*out*/, size_t *msize/*out*/);
+
/* Reference specific functions */
H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt);
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index bbc698f..6e2c8a7 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -230,6 +230,9 @@ H5T_vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc)
/* Mark this type as being stored in memory */
dt->shared->u.vlen.loc=H5T_LOC_MEMORY;
+ /* Turn on the force conversion */
+ /*dt->shared->force_conv = TRUE;*/
+
if(dt->shared->u.vlen.type==H5T_VLEN_SEQUENCE) {
/* size in memory, disk size is different */
dt->shared->size = sizeof(hvl_t);
@@ -266,6 +269,11 @@ H5T_vlen_set_loc(const H5T_t *dt, H5F_t *f, H5T_loc_t loc)
/* Mark this type as being stored on disk */
dt->shared->u.vlen.loc=H5T_LOC_DISK;
+ /* Turn off force conversion for the case of disk to disk copying.
+ * Simply copy VL data without conversion. It's mainly used by
+ * H5Dmodify_dtype function. */
+ /*dt->shared->force_conv = FALSE;*/
+
/*
* Size of element on disk is 4 bytes for the length, plus the size
* of an address in this file, plus 4 bytes for the size of a heap
diff --git a/src/H5Z.c b/src/H5Z.c
index de26831..aab81ad 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -46,8 +46,9 @@ typedef struct H5Z_stats_t {
/* Enumerated type for dataset creation prelude callbacks */
typedef enum {
- H5Z_PRELUDE_CAN_APPLY, /* Call "can apply" callback */
- H5Z_PRELUDE_SET_LOCAL /* Call "set local" callback */
+ H5Z_PRELUDE_CAN_APPLY, /* Call "can apply" callback */
+ H5Z_PRELUDE_SET_LOCAL, /* Call "set local" callback */
+ H5Z_PRELUDE_RESET_LOCAL /* Call "reset local" callback */
} H5Z_prelude_type_t;
/* Local variables */
@@ -110,10 +111,14 @@ H5Z_init_interface (void)
if (H5Z_register (H5Z_SCALEOFFSET)<0)
HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register scaleoffset filter")
#endif /* H5_HAVE_FILTER_SCALEOFFSET */
+#ifdef H5_HAVE_FILTER_DTYPE_MODIFY
+ if (H5Z_register (H5Z_DTYPE_MODIFY)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register dtype modify filter")
+#endif /* H5_HAVE_FILTER_DTYPE_MODIFY */
-#if (defined H5_HAVE_FILTER_DEFLATE | defined H5_HAVE_FILTER_FLETCHER32 | defined H5_HAVE_FILTER_SHUFFLE | defined H5_HAVE_FILTER_SZIP | defined H5_HAVE_FILTER_NBIT | defined H5_HAVE_FILTER_SCALEOFFSET)
+#if (defined H5_HAVE_FILTER_DEFLATE | defined H5_HAVE_FILTER_FLETCHER32 | defined H5_HAVE_FILTER_SHUFFLE | defined H5_HAVE_FILTER_SZIP | defined H5_HAVE_FILTER_NBIT | defined H5_HAVE_FILTER_SCALEOFFSET | defined H5_HAVE_FILTER_DTYPE_MODIFY)
done:
-#endif /* (defined H5_HAVE_FILTER_DEFLATE | defined H5_HAVE_FILTER_FLETCHER32 | defined H5_HAVE_FILTER_SHUFFLE | defined H5_HAVE_FILTER_SZIP | defined H5_HAVE_FILTER_NBIT | defined H5_HAVE_FILTER_SCALEOFFSET) */
+#endif /* (defined H5_HAVE_FILTER_DEFLATE | defined H5_HAVE_FILTER_FLETCHER32 | defined H5_HAVE_FILTER_SHUFFLE | defined H5_HAVE_FILTER_SZIP | defined H5_HAVE_FILTER_NBIT | defined H5_HAVE_FILTER_SCALEOFFSET | defined H5_HAVE_FILTER_DTYPE_MODIFY) */
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -466,7 +471,8 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type)
+H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type,
+ hid_t file_id)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -547,7 +553,7 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty
/* Check if there is a "can apply" callback */
if(fclass->can_apply) {
/* Make callback to filter's "can apply" function */
- herr_t status=(fclass->can_apply)(dcpl_id, type_id, space_id);
+ herr_t status=(fclass->can_apply)(dcpl_id, type_id, space_id, file_id);
/* Check return value */
if(status<=0) {
@@ -571,7 +577,22 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty
/* Check if there is a "set local" callback */
if(fclass->set_local) {
/* Make callback to filter's "set local" function */
- if((fclass->set_local)(dcpl_id, type_id, space_id)<0) {
+ if((fclass->set_local)(dcpl_id, type_id, space_id, file_id)<0) {
+ /* We're leaving, so close dataspace */
+ if(H5I_dec_ref(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
+
+ /* Indicate error during filter callback */
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback")
+ } /* end if */
+ } /* end if */
+ break;
+
+ case H5Z_PRELUDE_RESET_LOCAL:
+ /* Check if there is a "reset local" callback */
+ if(fclass->reset_local) {
+ /* Make callback to filter's "set local" function */
+ if((fclass->reset_local)(dcpl_id, type_id, space_id, file_id)<0) {
/* We're leaving, so close dataspace */
if(H5I_dec_ref(space_id)<0)
HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace")
@@ -622,7 +643,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_can_apply (hid_t dcpl_id, hid_t type_id)
+H5Z_can_apply (hid_t dcpl_id, hid_t type_id, hid_t file_id)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -632,7 +653,7 @@ H5Z_can_apply (hid_t dcpl_id, hid_t type_id)
assert (H5I_DATATYPE==H5I_get_type(type_id));
/* Make "can apply" callbacks for filters in pipeline */
- if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY)<0)
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY, file_id)<0)
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "unable to apply filter")
done:
@@ -662,7 +683,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_set_local (hid_t dcpl_id, hid_t type_id)
+H5Z_set_local (hid_t dcpl_id, hid_t type_id, hid_t file_id)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -672,7 +693,7 @@ H5Z_set_local (hid_t dcpl_id, hid_t type_id)
assert (H5I_DATATYPE==H5I_get_type(type_id));
/* Make "set local" callbacks for filters in pipeline */
- if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL)<0)
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL, file_id)<0)
HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set")
done:
@@ -681,6 +702,46 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Z_reset_local
+ *
+ * Purpose: Makes callbacks to modify dataset creation list property
+ * settings for filters on an existing dataset, based on the
+ * datatype and dataspace of that dataset (chunk) and the file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * 16 Sept 2007
+ *
+ * Notes:
+ * The chunk dimensions are used to create a dataspace, instead
+ * of passing in the dataset's dataspace, since the chunk
+ * dimensions are what the I/O filter will actually see
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_reset_local (hid_t dcpl_id, hid_t type_id, hid_t file_id)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_reset_local,FAIL)
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+ assert (H5I_DATATYPE==H5I_get_type(type_id));
+
+ /* Make "reset local" callbacks for filters in pipeline */
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_RESET_LOCAL, file_id)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_reset_local() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Z_modify
*
* Purpose: Modify filter parameters for specified pipeline.
diff --git a/src/H5Zdeflate.c b/src/H5Zdeflate.c
index 56b910b..a954c2a 100644
--- a/src/H5Zdeflate.c
+++ b/src/H5Zdeflate.c
@@ -45,6 +45,7 @@ const H5Z_class_t H5Z_DEFLATE[1] = {{
"deflate", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
H5Z_filter_deflate, /* The actual filter function */
}};
diff --git a/src/H5Zfletcher32.c b/src/H5Zfletcher32.c
index aa3a173..2434537 100644
--- a/src/H5Zfletcher32.c
+++ b/src/H5Zfletcher32.c
@@ -42,6 +42,7 @@ const H5Z_class_t H5Z_FLETCHER32[1] = {{
"fletcher32", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
H5Z_filter_fletcher32, /* The actual filter function */
}};
diff --git a/src/H5Znbit.c b/src/H5Znbit.c
index 7a29d45..9827a9d 100644
--- a/src/H5Znbit.c
+++ b/src/H5Znbit.c
@@ -38,8 +38,10 @@ typedef struct {
} parms_atomic;
/* Local function prototypes */
-static herr_t H5Z_can_apply_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id);
-static herr_t H5Z_set_local_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+static herr_t H5Z_can_apply_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
+static herr_t H5Z_set_local_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
static size_t H5Z_filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[],
size_t nbytes, size_t *buf_size, void **buf);
@@ -88,6 +90,7 @@ H5Z_class_t H5Z_NBIT[1] = {{
"nbit", /* Filter name for debugging */
H5Z_can_apply_nbit, /* The "can apply" callback */
H5Z_set_local_nbit, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
H5Z_filter_nbit, /* The actual filter function */
}};
@@ -131,7 +134,8 @@ static unsigned parms_index = 0;
*-------------------------------------------------------------------------
*/
static herr_t
-H5Z_can_apply_nbit(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id)
+H5Z_can_apply_nbit(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id,
+ hid_t UNUSED file_id)
{
const H5T_t *type; /* Datatype */
herr_t ret_value = TRUE; /* Return value */
@@ -728,7 +732,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5Z_set_local_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id)
+H5Z_set_local_nbit(hid_t dcpl_id, hid_t type_id, hid_t space_id, hid_t UNUSED file_id)
{
H5P_genplist_t *dcpl_plist; /* Property list pointer */
const H5T_t *type; /* Datatype */
diff --git a/src/H5Zpkg.h b/src/H5Zpkg.h
index 9cd126e..9871120 100644
--- a/src/H5Zpkg.h
+++ b/src/H5Zpkg.h
@@ -22,7 +22,9 @@
/* Include private header file */
#include "H5Zprivate.h" /* Filter functions */
-
+#include "H5Oprivate.h" /* Object headers */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Sprivate.h" /* Space */
/* The initial version of the format */
#define H5O_PLINE_VERSION_1 1
@@ -80,6 +82,13 @@ H5_DLLVAR H5Z_class_t H5Z_NBIT[1];
H5_DLLVAR H5Z_class_t H5Z_SCALEOFFSET[1];
#endif /* H5_HAVE_FILTER_SCALEOFFSET */
+#ifdef H5_HAVE_FILTER_DTYPE_MODIFY
+/*
+ * datatype modification filter
+ */
+H5_DLLVAR H5Z_class_t H5Z_DTYPE_MODIFY[1];
+#endif /* H5_HAVE_FILTER_DTYPE_MODIFY */
+
/* Package-local function prototypes */
H5_DLL void H5Z_update_class_vers(H5Z_class_t * old_vers, H5Z_class_t * curr_vers);
diff --git a/src/H5Zprivate.h b/src/H5Zprivate.h
index cd67e96..890125c 100644
--- a/src/H5Zprivate.h
+++ b/src/H5Zprivate.h
@@ -84,8 +84,9 @@ H5_DLL herr_t H5Z_pipeline(const struct H5O_pline_t *pline,
size_t *nbytes/*in,out*/, size_t *buf_size/*in,out*/,
void **buf/*in,out*/);
H5_DLL H5Z_class_t *H5Z_find(H5Z_filter_t id);
-H5_DLL herr_t H5Z_can_apply(hid_t dcpl_id, hid_t type_id);
-H5_DLL herr_t H5Z_set_local(hid_t dcpl_id, hid_t type_id);
+H5_DLL herr_t H5Z_can_apply(hid_t dcpl_id, hid_t type_id, hid_t file_id);
+H5_DLL herr_t H5Z_set_local(hid_t dcpl_id, hid_t type_id, hid_t file_id);
+H5_DLL herr_t H5Z_reset_local(hid_t dcpl_id, hid_t type_id, hid_t file_id);
H5_DLL H5Z_filter_info_t *H5Z_filter_info(const struct H5O_pline_t *pline,
H5Z_filter_t filter);
H5_DLL htri_t H5Z_all_filters_avail(const struct H5O_pline_t *pline);
diff --git a/src/H5Zpublic.h b/src/H5Zpublic.h
index 1fac71c..7ef9e98 100644
--- a/src/H5Zpublic.h
+++ b/src/H5Zpublic.h
@@ -41,6 +41,7 @@ typedef int H5Z_filter_t;
#define H5Z_FILTER_SZIP 4 /*szip compression */
#define H5Z_FILTER_NBIT 5 /*nbit compression */
#define H5Z_FILTER_SCALEOFFSET 6 /*scale+offset compression */
+#define H5Z_FILTER_DTYPE_MODIFY 7 /*modification of dataset's datatype*/
#define H5Z_FILTER_RESERVED 256 /*filter ids below this value are reserved for library use */
#define H5Z_FILTER_MAX 65535 /*maximum filter id */
@@ -122,13 +123,13 @@ extern "C" {
/*
* Before a dataset gets created, the "can_apply" callbacks for any filters used
* in the dataset creation property list are called
- * with the dataset's dataset creation property list, the dataset's datatype and
- * a dataspace describing a chunk (for chunked dataset storage).
+ * with the dataset's dataset creation property list, the dataset's datatype,
+ * a dataspace describing a chunk (for chunked dataset storage), and a file ID.
*
* The "can_apply" callback must determine if the combination of the dataset
- * creation property list setting, the datatype and the dataspace represent a
- * valid combination to apply this filter to. For example, some cases of
- * invalid combinations may involve the filter not operating correctly on
+ * creation property list setting, the datatype, the dataspace, and the file
+ * represents a valid combination to apply this filter to. For example, some cases
+ * of invalid combinations may involve the filter not operating correctly on
* certain datatypes (or certain datatype sizes), or certain sizes of the chunk
* dataspace.
*
@@ -139,7 +140,8 @@ extern "C" {
* The "can_apply" callback returns positive a valid combination, zero for an
* invalid combination and negative for an error.
*/
-typedef herr_t (*H5Z_can_apply_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+typedef herr_t (*H5Z_can_apply_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t file_id);
/*
* After the "can_apply" callbacks are checked for new datasets, the "set_local"
@@ -147,8 +149,10 @@ typedef herr_t (*H5Z_can_apply_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space
* called. These callbacks receive the dataset's private copy of the dataset
* creation property list passed in to H5Dcreate (i.e. not the actual property
* list passed in to H5Dcreate) and the datatype ID passed in to H5Dcreate
- * (which is not copied and should not be modified) and a dataspace describing
- * the chunk (for chunked dataset storage) (which should also not be modified).
+ * (which is not copied and should not be modified), a dataspace describing
+ * the chunk (for chunked dataset storage) (which should also not be modified),
+ * and an identity for the file which should be registered and closed by the
+ * caller function.
*
* The "set_local" callback must set any parameters that are specific to this
* dataset, based on the combination of the dataset creation property list
@@ -161,8 +165,13 @@ typedef herr_t (*H5Z_can_apply_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space
*
* The "set_local" callback must return non-negative on success and negative
* for an error.
+ *
+ * After the dataset is created and reopened, some filters may need these info
+ * again. The function prototype of "reset_local" callback is identical to
+ * the "set_local".
*/
-typedef herr_t (*H5Z_set_local_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+typedef herr_t (*H5Z_set_local_func_t)(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t file_id);
/*
* A filter gets definition flags and invocation flags (defined above), the
@@ -195,6 +204,7 @@ typedef struct H5Z_class_t {
const char *name; /* Comment for debugging */
H5Z_can_apply_func_t can_apply; /* The "can apply" callback for a filter */
H5Z_set_local_func_t set_local; /* The "set local" callback for a filter */
+ H5Z_set_local_func_t reset_local; /* The "reset local" callback for a filter */
H5Z_func_t filter; /* The actual filter function */
} H5Z_class_t;
diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c
index 7482275..12e9aee 100644
--- a/src/H5Zscaleoffset.c
+++ b/src/H5Zscaleoffset.c
@@ -40,13 +40,15 @@ enum H5Z_scaleoffset_type {t_bad=0, t_uchar=1, t_ushort, t_uint, t_ulong, t_ulon
/* Local function prototypes */
static double H5Z_scaleoffset_rnd(double val);
-static herr_t H5Z_can_apply_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+static herr_t H5Z_can_apply_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
static enum H5Z_scaleoffset_type H5Z_scaleoffset_get_type(unsigned dtype_class,
unsigned dtype_size, unsigned dtype_sign);
static herr_t H5Z_scaleoffset_set_parms_fillval(H5P_genplist_t *dcpl_plist,
const H5T_t *type, enum H5Z_scaleoffset_type scale_type, unsigned cd_values[],
int need_convert, hid_t dxpl_id);
-static herr_t H5Z_set_local_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+static herr_t H5Z_set_local_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
static size_t H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
static void H5Z_scaleoffset_convert(void *buf, unsigned d_nelmts, size_t dtype_size);
@@ -88,6 +90,7 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
"scaleoffset", /* Filter name for debugging */
H5Z_can_apply_scaleoffset, /* The "can apply" callback */
H5Z_set_local_scaleoffset, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
H5Z_filter_scaleoffset, /* The actual filter function */
}};
@@ -585,7 +588,8 @@ H5Z_class_t H5Z_SCALEOFFSET[1] = {{
*-------------------------------------------------------------------------
*/
static herr_t
-H5Z_can_apply_scaleoffset(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id)
+H5Z_can_apply_scaleoffset(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id,
+ hid_t UNUSED file_id)
{
const H5T_t *type; /* Datatype */
H5T_class_t dtype_class; /* Datatype's class */
@@ -752,7 +756,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5Z_set_local_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t space_id)
+H5Z_set_local_scaleoffset(hid_t dcpl_id, hid_t type_id, hid_t space_id, hid_t UNUSED file_id)
{
H5P_genplist_t *dcpl_plist; /* Property list pointer */
const H5T_t *type; /* Datatype */
@@ -904,7 +908,6 @@ done:
* Monday, February 7, 2005
*
* Modifications:
- *
*-------------------------------------------------------------------------
*/
static size_t
diff --git a/src/H5Zshuffle.c b/src/H5Zshuffle.c
index c203ed9..cc0bb5a 100644
--- a/src/H5Zshuffle.c
+++ b/src/H5Zshuffle.c
@@ -40,6 +40,7 @@ const H5Z_class_t H5Z_SHUFFLE[1] = {{
"shuffle", /* Filter name for debugging */
NULL, /* The "can apply" callback */
H5Z_set_local_shuffle, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
H5Z_filter_shuffle, /* The actual filter function */
}};
diff --git a/src/H5Zszip.c b/src/H5Zszip.c
index cdc26aa..191d7e7 100644
--- a/src/H5Zszip.c
+++ b/src/H5Zszip.c
@@ -34,8 +34,10 @@
#endif
/* Local function prototypes */
-static herr_t H5Z_can_apply_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id);
-static herr_t H5Z_set_local_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+static herr_t H5Z_can_apply_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
+static herr_t H5Z_set_local_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t UNUSED file_id);
static size_t H5Z_filter_szip (unsigned flags, size_t cd_nelmts,
const unsigned cd_values[], size_t nbytes, size_t *buf_size, void **buf);
@@ -48,6 +50,7 @@ H5Z_class_t H5Z_SZIP[1] = {{
"szip", /* Filter name for debugging */
H5Z_can_apply_szip, /* The "can apply" callback */
H5Z_set_local_szip, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
H5Z_filter_szip, /* The actual filter function */
}};
@@ -84,7 +87,8 @@ H5Z_class_t H5Z_SZIP[1] = {{
*-------------------------------------------------------------------------
*/
static herr_t
-H5Z_can_apply_szip(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id)
+H5Z_can_apply_szip(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id,
+ hid_t UNUSED file_id)
{
const H5T_t *type; /* Datatype */
unsigned dtype_size; /* Datatype's size (in bits) */
@@ -141,7 +145,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5Z_set_local_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id)
+H5Z_set_local_szip(hid_t dcpl_id, hid_t type_id, hid_t space_id, hid_t UNUSED file_id)
{
H5P_genplist_t *dcpl_plist; /* Property list pointer */
const H5T_t *type; /* Datatype */
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 0c89e98..bda24d8 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -83,6 +83,9 @@
/* Define if support for deflate (zlib) filter is enabled */
#undef HAVE_FILTER_DEFLATE
+/* Define if support for datatype modification filter is enabled */
+#undef HAVE_FILTER_DTYPE_MODIFY
+
/* Define if support for Fletcher32 checksum is enabled */
#undef HAVE_FILTER_FLETCHER32
diff --git a/src/Makefile.am b/src/Makefile.am
index d742282..8c42613 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -91,7 +91,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Topaque.c \
H5Torder.c \
H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvisit.c H5Tvlen.c H5TS.c H5V.c H5WB.c H5Z.c \
- H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \
+ H5Zdeflate.c H5Zdtype_modify.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \
H5Zscaleoffset.c H5Ztrans.c
diff --git a/src/Makefile.in b/src/Makefile.in
index 1dbf810..93df9f6 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -117,8 +117,9 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5Tfixed.lo H5Tfloat.lo H5Tinit.lo H5Tnative.lo H5Toffset.lo \
H5Toh.lo H5Topaque.lo H5Torder.lo H5Tpad.lo H5Tprecis.lo \
H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo H5TS.lo H5V.lo H5WB.lo \
- H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \
- H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo
+ H5Z.lo H5Zdeflate.lo H5Zdtype_modify.lo H5Zfletcher32.lo \
+ H5Znbit.lo H5Zshuffle.lo H5Zszip.lo H5Zscaleoffset.lo \
+ H5Ztrans.lo
libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS)
libhdf5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -275,6 +276,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
@@ -448,7 +450,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Topaque.c \
H5Torder.c \
H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvisit.c H5Tvlen.c H5TS.c H5V.c H5WB.c H5Z.c \
- H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \
+ H5Zdeflate.c H5Zdtype_modify.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \
H5Zscaleoffset.c H5Ztrans.c
@@ -780,6 +782,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5WB.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Z.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Zdeflate.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Zdtype_modify.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Zfletcher32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Znbit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Zscaleoffset.Plo@am__quote@
diff --git a/test/Makefile.am b/test/Makefile.am
index e5a1394..538c87d 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -36,7 +36,7 @@ SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT)
# These tests (fheap, btree2) are under development and are not used by
# the library yet. Move them to the end so that their failure do not block
# other current library code tests.
-TEST_PROG=testhdf5 lheap ohdr stab gheap cache cache_api \
+TEST_PROG=testhdf5 lheap ohdr stab gheap cache cache_api change_dtypes \
pool hyperslab istore bittests dt_arith \
dtypes dsets cmpd_dset extend external objcopy links unlink big mtime \
fillval mount flush1 flush2 enum \
@@ -116,7 +116,7 @@ CHECK_CLEANFILES+=cmpd_dset.h5 compact_dataset.h5 dataset.h5 extend.h5 istore.h5
family_file000[0-3][0-9].h5 multi_file-[rs].h5 core_file \
new_move_[ab].h5 ntypes.h5 dangle.h5 error_test.h5 err_compat.h5 \
dtransform.h5 test_filters.h5 get_file_name.h5 tstint[1-2].h5 \
- unlink_chunked.h5 btree2.h5 \
+ unlink_chunked.h5 btree2.h5 modify_types.h5 \
objcopy_src.h5 objcopy_dst.h5 objcopy_ext.dat trefer1.h5 trefer2.h5
# Sources for testhdf5 executable
diff --git a/test/Makefile.in b/test/Makefile.in
index add9df2..d9dc588 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -71,16 +71,16 @@ am_libh5test_la_OBJECTS = h5test.lo testframe.lo cache_common.lo
libh5test_la_OBJECTS = $(am_libh5test_la_OBJECTS)
am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \
stab$(EXEEXT) gheap$(EXEEXT) cache$(EXEEXT) cache_api$(EXEEXT) \
- pool$(EXEEXT) hyperslab$(EXEEXT) istore$(EXEEXT) \
- bittests$(EXEEXT) dt_arith$(EXEEXT) dtypes$(EXEEXT) \
- dsets$(EXEEXT) cmpd_dset$(EXEEXT) extend$(EXEEXT) \
- external$(EXEEXT) objcopy$(EXEEXT) links$(EXEEXT) \
- unlink$(EXEEXT) big$(EXEEXT) mtime$(EXEEXT) fillval$(EXEEXT) \
- mount$(EXEEXT) flush1$(EXEEXT) flush2$(EXEEXT) enum$(EXEEXT) \
- set_extent$(EXEEXT) ttsafe$(EXEEXT) getname$(EXEEXT) \
- vfd$(EXEEXT) ntypes$(EXEEXT) dangle$(EXEEXT) \
- dtransform$(EXEEXT) reserved$(EXEEXT) cross_read$(EXEEXT) \
- btree2$(EXEEXT) fheap$(EXEEXT)
+ change_dtypes$(EXEEXT) pool$(EXEEXT) hyperslab$(EXEEXT) \
+ istore$(EXEEXT) bittests$(EXEEXT) dt_arith$(EXEEXT) \
+ dtypes$(EXEEXT) dsets$(EXEEXT) cmpd_dset$(EXEEXT) \
+ extend$(EXEEXT) external$(EXEEXT) objcopy$(EXEEXT) \
+ links$(EXEEXT) unlink$(EXEEXT) big$(EXEEXT) mtime$(EXEEXT) \
+ fillval$(EXEEXT) mount$(EXEEXT) flush1$(EXEEXT) \
+ flush2$(EXEEXT) enum$(EXEEXT) set_extent$(EXEEXT) \
+ ttsafe$(EXEEXT) getname$(EXEEXT) vfd$(EXEEXT) ntypes$(EXEEXT) \
+ dangle$(EXEEXT) dtransform$(EXEEXT) reserved$(EXEEXT) \
+ cross_read$(EXEEXT) btree2$(EXEEXT) fheap$(EXEEXT)
am__EXEEXT_2 = gen_bogus$(EXEEXT) gen_cross$(EXEEXT) \
gen_deflate$(EXEEXT) gen_filters$(EXEEXT) \
gen_new_array$(EXEEXT) gen_new_fill$(EXEEXT) \
@@ -109,6 +109,10 @@ cache_api_SOURCES = cache_api.c
cache_api_OBJECTS = cache_api.$(OBJEXT)
cache_api_LDADD = $(LDADD)
cache_api_DEPENDENCIES = libh5test.la $(LIBHDF5)
+change_dtypes_SOURCES = change_dtypes.c
+change_dtypes_OBJECTS = change_dtypes.$(OBJEXT)
+change_dtypes_LDADD = $(LDADD)
+change_dtypes_DEPENDENCIES = libh5test.la $(LIBHDF5)
cmpd_dset_SOURCES = cmpd_dset.c
cmpd_dset_OBJECTS = cmpd_dset.$(OBJEXT)
cmpd_dset_LDADD = $(LDADD)
@@ -328,8 +332,8 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c \
- cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c \
- dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \
+ cache_api.c change_dtypes.c cmpd_dset.c cross_read.c dangle.c \
+ dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \
error_test.c extend.c external.c fheap.c fillval.c flush1.c \
flush2.c gen_bogus.c gen_cross.c gen_deflate.c gen_filters.c \
gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \
@@ -339,16 +343,17 @@ SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c cache.c \
set_extent.c space_overflow.c stab.c $(testhdf5_SOURCES) \
testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
DIST_SOURCES = $(libh5test_la_SOURCES) big.c bittests.c btree2.c \
- cache.c cache_api.c cmpd_dset.c cross_read.c dangle.c dsets.c \
- dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \
- error_test.c extend.c external.c fheap.c fillval.c flush1.c \
- flush2.c gen_bogus.c gen_cross.c gen_deflate.c gen_filters.c \
- gen_new_array.c gen_new_fill.c gen_new_group.c gen_new_mtime.c \
- gen_new_super.c gen_noencoder.c gen_nullspace.c gen_udlinks.c \
- getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \
- mtime.c ntypes.c objcopy.c ohdr.c pool.c reserved.c \
- set_extent.c space_overflow.c stab.c $(testhdf5_SOURCES) \
- testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
+ cache.c cache_api.c change_dtypes.c cmpd_dset.c cross_read.c \
+ dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c \
+ err_compat.c error_test.c extend.c external.c fheap.c \
+ fillval.c flush1.c flush2.c gen_bogus.c gen_cross.c \
+ gen_deflate.c gen_filters.c gen_new_array.c gen_new_fill.c \
+ gen_new_group.c gen_new_mtime.c gen_new_super.c \
+ gen_noencoder.c gen_nullspace.c gen_udlinks.c getname.c \
+ gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c \
+ ntypes.c objcopy.c ohdr.c pool.c reserved.c set_extent.c \
+ space_overflow.c stab.c $(testhdf5_SOURCES) testmeta.c \
+ $(ttsafe_SOURCES) unlink.c vfd.c
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -476,6 +481,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
@@ -599,8 +605,9 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog cmpd_dset.h5 \
direct_file.h5 family_file000[0-3][0-9].h5 multi_file-[rs].h5 \
core_file new_move_[ab].h5 ntypes.h5 dangle.h5 error_test.h5 \
err_compat.h5 dtransform.h5 test_filters.h5 get_file_name.h5 \
- tstint[1-2].h5 unlink_chunked.h5 btree2.h5 objcopy_src.h5 \
- objcopy_dst.h5 objcopy_ext.dat trefer1.h5 trefer2.h5
+ tstint[1-2].h5 unlink_chunked.h5 btree2.h5 modify_types.h5 \
+ objcopy_src.h5 objcopy_dst.h5 objcopy_ext.dat trefer1.h5 \
+ trefer2.h5
INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src
# Test script for error_test and err_compat
@@ -615,7 +622,7 @@ SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT)
# These tests (fheap, btree2) are under development and are not used by
# the library yet. Move them to the end so that their failure do not block
# other current library code tests.
-TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api \
+TEST_PROG = testhdf5 lheap ohdr stab gheap cache cache_api change_dtypes \
pool hyperslab istore bittests dt_arith \
dtypes dsets cmpd_dset extend external objcopy links unlink big mtime \
fillval mount flush1 flush2 enum \
@@ -750,6 +757,9 @@ cache$(EXEEXT): $(cache_OBJECTS) $(cache_DEPENDENCIES)
cache_api$(EXEEXT): $(cache_api_OBJECTS) $(cache_api_DEPENDENCIES)
@rm -f cache_api$(EXEEXT)
$(LINK) $(cache_api_OBJECTS) $(cache_api_LDADD) $(LIBS)
+change_dtypes$(EXEEXT): $(change_dtypes_OBJECTS) $(change_dtypes_DEPENDENCIES)
+ @rm -f change_dtypes$(EXEEXT)
+ $(LINK) $(change_dtypes_OBJECTS) $(change_dtypes_LDADD) $(LIBS)
cmpd_dset$(EXEEXT): $(cmpd_dset_OBJECTS) $(cmpd_dset_DEPENDENCIES)
@rm -f cmpd_dset$(EXEEXT)
$(LINK) $(cmpd_dset_OBJECTS) $(cmpd_dset_LDADD) $(LIBS)
@@ -910,6 +920,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache_api.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache_common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/change_dtypes.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmpd_dset.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cross_read.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dangle.Po@am__quote@
diff --git a/test/change_dtypes.c b/test/change_dtypes.c
new file mode 100644
index 0000000..1873316
--- /dev/null
+++ b/test/change_dtypes.c
@@ -0,0 +1,764 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Raymond Lu <slu@hdfgroup.org>
+ * 19 November 2007
+ */
+
+#include "h5test.h"
+
+#define STR_LEN 16
+#define NX 10u
+#define NY 20u
+#define MX 100u
+#define MY 200u
+#define CPTR(VAR,CONST) ((VAR)=(CONST),&(VAR))
+
+const char *FILENAME[] = {
+ "modify_types",
+ NULL
+};
+
+const char *DSET_NAME[] = {
+ "integer",
+ "float1",
+ "float2",
+ "string",
+ "vlstring",
+ "bitfield",
+ "opaque",
+ "enum",
+ "array",
+ NULL
+};
+
+typedef enum {
+ E1_RED,
+ E1_GREEN,
+ E1_BLUE,
+ E1_WHITE,
+ E1_BLACK
+} c_e1;
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_integer
+ *
+ * Purpose: Creates a simple dataset of an integer type and tries to
+ * change the datatype.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 19 November 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_integer(hid_t file)
+{
+ hid_t dset;
+ hid_t space;
+ hsize_t dims[2] = {NX, NY};
+ herr_t ret;
+
+ if((space=H5Screate_simple(2, dims, NULL)) < 0)
+ TEST_ERROR;
+
+ if((dset=H5Dcreate2(file, DSET_NAME[0], H5T_STD_U32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, H5T_STD_I16BE);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, H5T_STD_I32BE);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, H5T_IEEE_F32BE);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ if(H5Dmodify_dtype(dset, H5T_IEEE_F64LE) < 0)
+ TEST_ERROR;
+
+ if(H5Dmodify_dtype(dset, H5T_STD_I64LE) < 0)
+ TEST_ERROR;
+
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5_FAILED();
+ H5E_BEGIN_TRY {
+ H5Sclose(space);
+ H5Dclose(dset);
+ } H5E_END_TRY;
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_float
+ *
+ * Purpose: Creates a simple dataset of a float type and tries to
+ * change the datatype.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 19 November 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_float(hid_t file)
+{
+ hid_t dset;
+ hid_t space;
+ hid_t dcpl_id;
+ float fill_value = 100.123;
+ double fill_ret;
+ double data_out[NX][NY];
+ hsize_t dims[2] = {NX, NY};
+ hsize_t chunk_dims[2] = {NX/2, NY/2};
+ unsigned int i, j;
+ herr_t ret;
+
+ if((space=H5Screate_simple(2, dims, NULL)) < 0)
+ TEST_ERROR;
+
+ if((dcpl_id = H5Pcreate(H5P_DATASET_CREATE)) < 0)
+ TEST_ERROR;
+
+ if(H5Pset_fill_value(dcpl_id, H5T_NATIVE_FLOAT, &fill_value) < 0)
+ TEST_ERROR;
+
+ if((dset=H5Dcreate2(file, DSET_NAME[1], H5T_NATIVE_FLOAT, space, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, H5T_STD_U32BE);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ if(H5Dmodify_dtype(dset, H5T_NATIVE_DOUBLE) < 0)
+ TEST_ERROR;
+
+ if(H5Pget_fill_value(dcpl_id, H5T_NATIVE_DOUBLE, &fill_ret) < 0)
+ TEST_ERROR;
+
+ if(!DBL_ABS_EQUAL(fill_ret, fill_value))
+ TEST_ERROR;
+
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR;
+
+ /* Create a chunk dataset with fill value and space allocation early.
+ * Enable the filter for modifying dataset's datatype. Verify the correctness
+ * of the fill value. */
+ if(H5Pset_dtype_modifiable(dcpl_id)<0)
+ TEST_ERROR;
+
+ /* Set chunking */
+ if(H5Pset_chunk(dcpl_id, 2, chunk_dims)<0)
+ TEST_ERROR;
+
+ /* Set space allocation early */
+ if(H5Pset_alloc_time(dcpl_id, H5D_ALLOC_TIME_EARLY) < 0)
+ TEST_ERROR;
+
+ if((dset=H5Dcreate2(file, DSET_NAME[2], H5T_NATIVE_FLOAT, space, H5P_DEFAULT, dcpl_id, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ /* Change dataset's type */
+ if(H5Dmodify_dtype(dset, H5T_NATIVE_DOUBLE) < 0)
+ TEST_ERROR;
+
+ /* Verify fill value is still correct */
+ if(H5Pget_fill_value(dcpl_id, H5T_NATIVE_DOUBLE, &fill_ret) < 0)
+ TEST_ERROR;
+
+ if(!DBL_ABS_EQUAL(fill_ret, fill_value))
+ TEST_ERROR;
+
+ if(H5Dread(dset, H5T_NATIVE_DOUBLE, space, H5S_ALL, H5P_DEFAULT, data_out) < 0)
+ TEST_ERROR;
+
+ for(i=0; i<NX; i++) {
+ for(j=0; j<NY; j++) {
+ if(!DBL_ABS_EQUAL(fill_ret, data_out[i][j]))
+ TEST_ERROR;
+ }
+ }
+
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR;
+
+ if(H5Pclose(dcpl_id) < 0)
+ TEST_ERROR;
+
+ if(H5Sclose(space) < 0)
+ TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5_FAILED();
+ H5E_BEGIN_TRY {
+ H5Sclose(space);
+ H5Pclose(dcpl_id);
+ H5Dclose(dset);
+ } H5E_END_TRY;
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_string
+ *
+ * Purpose: Creates a simple dataset of a string type and tries to
+ * change the datatype.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 19 November 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_string(hid_t file)
+{
+ hid_t dset;
+ hid_t space, type1, type2;
+ hsize_t dims[2] = {NX, NY};
+ herr_t ret;
+
+ if((space=H5Screate_simple(2, dims, NULL)) < 0)
+ TEST_ERROR;
+
+ /* create a fix-sized string datatype */
+ if((type1 = H5Tcopy(H5T_C_S1)) < 0)
+ TEST_ERROR;
+
+ if(H5Tset_size(type1, STR_LEN) < 0)
+ TEST_ERROR;
+
+ if(H5Tset_strpad(type1, H5T_STR_NULLTERM) < 0)
+ TEST_ERROR;
+
+ /* Create a dataset of fix-sized string */
+ if((dset=H5Dcreate2(file, DSET_NAME[3], type1, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ if(H5Tset_size(type1, STR_LEN - 1) < 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, type1);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ if(H5Tset_size(type1, STR_LEN + 4) < 0)
+ TEST_ERROR;
+
+ if(H5Dmodify_dtype(dset, type1) < 0)
+ TEST_ERROR;
+
+
+ if(H5Tset_size(type1, H5T_VARIABLE) < 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, type1);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR;
+
+
+ /* Create a dataset of vl string */
+ if((dset=H5Dcreate2(file, DSET_NAME[4], type1, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ /* Create a fix-size string datatype */
+ if((type2 = H5Tcopy(H5T_C_S1)) < 0)
+ TEST_ERROR;
+
+ if(H5Tset_size(type2, STR_LEN) < 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, type2);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ if(H5Tset_size(type2, H5T_VARIABLE) < 0)
+ TEST_ERROR;
+
+ if(H5Dmodify_dtype(dset, type2) < 0)
+ TEST_ERROR;
+
+ if(H5Tclose(type1) < 0)
+ TEST_ERROR;
+
+ if(H5Tclose(type2) < 0)
+ TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5_FAILED();
+ H5E_BEGIN_TRY {
+ H5Sclose(space);
+ H5Tclose(type1);
+ H5Tclose(type2);
+ H5Dclose(dset);
+ } H5E_END_TRY;
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_bitfield
+ *
+ * Purpose: Creates a simple dataset of a bitfield type and tries to
+ * change the datatype.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 19 November 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_bitfield(hid_t file)
+{
+ hid_t dset;
+ hid_t space;
+ hsize_t dims[2] = {NX, NY};
+ herr_t ret;
+
+ if((space=H5Screate_simple(2, dims, NULL)) < 0)
+ TEST_ERROR;
+
+ if((dset=H5Dcreate2(file, DSET_NAME[5], H5T_STD_B32BE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, H5T_STD_B16BE);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, H5T_IEEE_F32BE);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ if(H5Dmodify_dtype(dset, H5T_STD_B64LE) < 0)
+ TEST_ERROR;
+
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5_FAILED();
+ H5E_BEGIN_TRY {
+ H5Sclose(space);
+ H5Dclose(dset);
+ } H5E_END_TRY;
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_opaque
+ *
+ * Purpose: Creates a simple dataset of an opaque type and tries to
+ * change the datatype.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 19 November 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_opaque(hid_t file)
+{
+ hid_t dset;
+ hid_t space, type, new_type;
+ hsize_t dims[2] = {NX, NY};
+ const char *tag = "this is a tag";
+ herr_t ret;
+
+ if((space=H5Screate_simple(2, dims, NULL)) < 0)
+ TEST_ERROR;
+
+ if((type = H5Tcreate(H5T_OPAQUE, 4)) < 0)
+ TEST_ERROR;
+
+ if(H5Tset_tag(type, tag) < 0)
+ TEST_ERROR;
+
+ if((dset=H5Dcreate2(file, DSET_NAME[6], type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ /* Create a smaller opaque type and try to change the type to it.
+ * It should fail. */
+ if((new_type = H5Tcreate(H5T_OPAQUE, 2)) < 0)
+ TEST_ERROR;
+
+ if(H5Tset_tag(new_type, tag) < 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, new_type);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ if(H5Tclose(new_type) < 0)
+ TEST_ERROR;
+
+ /* Create a bigger opaque type and try to change the type to it.
+ * It should succeed. */
+ if((new_type = H5Tcreate(H5T_OPAQUE, 6)) < 0)
+ TEST_ERROR;
+
+ if(H5Tset_tag(new_type, tag) < 0)
+ TEST_ERROR;
+
+ if(H5Dmodify_dtype(dset, new_type) < 0)
+ TEST_ERROR;
+
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR;
+
+ if(H5Tclose(new_type) < 0)
+ TEST_ERROR;
+
+ if(H5Tclose(type) < 0)
+ TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5_FAILED();
+ H5E_BEGIN_TRY {
+ H5Sclose(space);
+ H5Dclose(dset);
+ H5Tclose(new_type);
+ H5Tclose(type);
+ } H5E_END_TRY;
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_enum
+ *
+ * Purpose: Creates a simple dataset of an enum type and tries to
+ * change the datatype.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 19 November 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_enum(hid_t file)
+{
+ hid_t dset;
+ hid_t space, type, new_type;
+ hsize_t dims[2] = {NX, NY};
+ c_e1 val1;
+ int val2;
+ short val3;
+ herr_t ret;
+
+ if((space=H5Screate_simple(2, dims, NULL)) < 0)
+ TEST_ERROR;
+
+ if ((type = H5Tcreate(H5T_ENUM, sizeof(c_e1)))<0) TEST_ERROR;
+ if (H5Tenum_insert(type, "RED", CPTR(val1, E1_RED ))<0) TEST_ERROR;
+ if (H5Tenum_insert(type, "GREEN", CPTR(val1, E1_GREEN))<0) TEST_ERROR;
+ if (H5Tenum_insert(type, "BLUE", CPTR(val1, E1_BLUE ))<0) TEST_ERROR;
+ if (H5Tenum_insert(type, "WHITE", CPTR(val1, E1_WHITE))<0) TEST_ERROR;
+ if (H5Tenum_insert(type, "BLACK", CPTR(val1, E1_BLACK))<0) TEST_ERROR;
+
+ if((dset=H5Dcreate2(file, DSET_NAME[7], type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ /* Create a new enum type with less members and try to change the type to it.
+ * It should fail. */
+ if ((new_type = H5Tcreate(H5T_ENUM, sizeof(int)))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "RED", CPTR(val2, 10))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "GREEN", CPTR(val2, 11))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "BLUE", CPTR(val2, 12))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "WHITE", CPTR(val2, 13))<0) TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, new_type);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ if(H5Tclose(new_type) < 0)
+ TEST_ERROR;
+
+ /* Create an enum type with more members type and try to change the type to it.
+ * It should succeed. */
+ if ((new_type = H5Tcreate(H5T_ENUM, sizeof(short)))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "RED", CPTR(val3, 107))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "GREEN", CPTR(val3, 106))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "BLUE", CPTR(val3, 105))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "WHITE", CPTR(val3, 104))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "BLACK", CPTR(val3, 103))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "YELLOW", CPTR(val3, 102))<0) TEST_ERROR;
+ if (H5Tenum_insert(new_type, "CYAN", CPTR(val3, 101))<0) TEST_ERROR;
+
+ if(H5Dmodify_dtype(dset, new_type) < 0)
+ TEST_ERROR;
+
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR;
+
+ if(H5Tclose(new_type) < 0)
+ TEST_ERROR;
+
+ if(H5Tclose(type) < 0)
+ TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5_FAILED();
+ H5E_BEGIN_TRY {
+ H5Sclose(space);
+ H5Dclose(dset);
+ H5Tclose(new_type);
+ H5Tclose(type);
+ } H5E_END_TRY;
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_array
+ *
+ * Purpose: Creates a simple dataset of a named array type and tries to
+ * change the datatype.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 19 November 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_array(hid_t file)
+{
+ hid_t dset;
+ hid_t space, type, new_type;
+ hsize_t dims[2] = {NX, NY};
+ hsize_t tdims[] = {4,4};
+ hsize_t new_tdims[] = {2,2};
+ herr_t ret;
+
+ if((space=H5Screate_simple(2, dims, NULL)) < 0)
+ TEST_ERROR;
+
+ /* Make a named array datatype */
+ if((type = H5Tarray_create2(H5T_NATIVE_INT, 2, tdims)) < 0)
+ TEST_ERROR;
+
+ if(H5Tcommit2(file, "array type", type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0)
+ TEST_ERROR;
+
+ if((dset=H5Dcreate2(file, DSET_NAME[8], type, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ TEST_ERROR;
+
+ /* Create an array type with shorter dimensionality and try to change the type to it.
+ * It should fail. */
+ if((new_type = H5Tarray_create2(H5T_NATIVE_INT, 2, new_tdims)) < 0)
+ TEST_ERROR;
+
+ H5E_BEGIN_TRY {
+ ret = H5Dmodify_dtype(dset, new_type);
+ } H5E_END_TRY;
+
+ if(ret > 0)
+ TEST_ERROR;
+
+ if(H5Tclose(new_type) < 0)
+ TEST_ERROR;
+
+ /* Create a named array type of long int and try to change the type to it.
+ * It should succeed. */
+ if((new_type = H5Tarray_create2(H5T_NATIVE_LONG, 2, tdims)) < 0)
+ TEST_ERROR;
+
+ if(H5Tcommit2(file, "new array type", new_type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT) < 0)
+ TEST_ERROR;
+
+ if(H5Dmodify_dtype(dset, new_type) < 0)
+ TEST_ERROR;
+
+ if(H5Dclose(dset) < 0)
+ TEST_ERROR;
+
+ if(H5Tclose(new_type) < 0)
+ TEST_ERROR;
+
+ if(H5Tclose(type) < 0)
+ TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5_FAILED();
+ H5E_BEGIN_TRY {
+ H5Sclose(space);
+ H5Dclose(dset);
+ H5Tclose(new_type);
+ H5Tclose(type);
+ } H5E_END_TRY;
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Purpose: Test H5Dmodify_dtype for different kinds of datatypes.
+ * The test for compound type is in cmpd_dset.c.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 19 November 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+int main(void)
+{
+ hid_t fid, fapl_id;
+ char filename[256];
+ unsigned nerrors = 0;
+
+ h5_reset();
+
+ /* Create the file */
+ fapl_id = h5_fileaccess();
+ h5_fixname(FILENAME[0], fapl_id, filename, sizeof(filename));
+
+ if ((fid = H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
+ nerrors++;
+
+ TESTING("dataset of integer type:");
+ nerrors += test_integer(fid);
+
+ TESTING("dataset of floating number:");
+ nerrors += test_float(fid);
+
+ TESTING("dataset of string type:");
+ nerrors += test_string(fid);
+
+ TESTING("dataset of bitfield type:");
+ nerrors += test_bitfield(fid);
+
+ TESTING("dataset of opaque type:");
+ nerrors += test_opaque(fid);
+
+ TESTING("dataset of enum type:");
+ nerrors += test_enum(fid);
+
+ TESTING("dataset of array type:");
+ nerrors += test_array(fid);
+
+ if(H5Fclose(fid) < 0)
+ nerrors++;
+
+ if (nerrors) {
+ printf("***** %u FAILURE%s! *****\n",
+ nerrors, 1==nerrors?"":"S");
+ HDexit(1);
+ }
+
+ h5_cleanup(FILENAME, fapl_id);
+ puts("All tests for changing dataset's datatype passed.");
+
+ return 0;
+}
diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c
index 66993e0..7a7f8fa 100644
--- a/test/cmpd_dset.c
+++ b/test/cmpd_dset.c
@@ -30,6 +30,10 @@ const char *FILENAME[] = {
"cmpd_dset",
"src_subset",
"dst_subset",
+ "modify_chunked_type",
+ "modify_chunked_type_no_filter",
+ "modify_contiguous_type",
+ "modify_compact_type",
NULL
};
@@ -38,6 +42,7 @@ const char *DSET_NAME[] = {
"chunk_src_subset",
"contig_dst_subset",
"chunk_dst_subset",
+ "compact_dst_subset",
NULL
};
@@ -106,6 +111,7 @@ typedef struct {
float f, g, h[16], i, j;
double k, l, m, n;
long o, p, q;
+ hvl_t r;
} stype2;
typedef struct {
int a, b, c[8], d, e;
@@ -115,11 +121,34 @@ typedef struct {
float f, g, h[16], i, j;
double k, l, m, n;
long o, p, q;
- long_long r, s, t;
+ hvl_t r;
+ long_long s, t, u;
} stype4;
+/*#define NX 10u
+#define NY 20u*/
#define NX 100u
-#define NY 2000u
+#define NY 200u
+#define COMP_NX 8u
+#define COMP_NY 10u
+
+/* Non-default SOHM values for testing the filter of datatype modification */
+#define TEST_NUM_INDEXES 4
+const unsigned test_type_flags[H5O_SHMESG_MAX_NINDEXES] =
+ {H5O_MESG_FILL_FLAG,
+ H5O_MESG_DTYPE_FLAG | H5O_MESG_ATTR_FLAG,
+ H5O_MESG_SDSPACE_FLAG,
+ H5O_MESG_PLINE_FLAG,
+ 0, 0};
+#ifndef TMP
+const unsigned test_minsizes[H5O_SHMESG_MAX_NINDEXES] = {0, 2, 40, 100, 3, 1000};
+#define TEST_L2B 65
+#define TEST_B2L 64
+#else
+const unsigned test_minsizes[H5O_SHMESG_MAX_NINDEXES] = {250,250,250,250,250,250};
+#define TEST_L2B 50
+#define TEST_B2L 40
+#endif
/*-------------------------------------------------------------------------
@@ -854,7 +883,7 @@ error:
*-------------------------------------------------------------------------
*/
static void
-initialize_stype1(unsigned char *buf, const size_t num)
+initialize_stype1(void *buf, const size_t num)
{
int i, j;
stype1 *s_ptr;
@@ -897,7 +926,7 @@ initialize_stype1(unsigned char *buf, const size_t num)
*-------------------------------------------------------------------------
*/
static void
-initialize_stype2(unsigned char *buf, const size_t num)
+initialize_stype2(void *buf, const size_t num)
{
size_t i, j;
stype2 *s_ptr;
@@ -926,6 +955,11 @@ initialize_stype2(unsigned char *buf, const size_t num)
s_ptr->o = i*3+0;
s_ptr->p = i*3+1;
s_ptr->q = i*3+2;
+
+ s_ptr->r.p=HDmalloc(4*sizeof(unsigned int));
+ s_ptr->r.len=4;
+ for(j=0; j<4; j++)
+ ((unsigned int *)s_ptr->r.p)[j]=i*10+j;
}
}
@@ -944,7 +978,7 @@ initialize_stype2(unsigned char *buf, const size_t num)
*-------------------------------------------------------------------------
*/
static void
-initialize_stype3(unsigned char *buf, const size_t num)
+initialize_stype3(void *buf, const size_t num)
{
int i, j;
stype3 *s_ptr;
@@ -975,7 +1009,7 @@ initialize_stype3(unsigned char *buf, const size_t num)
*-------------------------------------------------------------------------
*/
static void
-initialize_stype4(unsigned char *buf, const size_t num)
+initialize_stype4(void *buf, const size_t num)
{
size_t i, j;
stype4 *s_ptr;
@@ -1005,9 +1039,14 @@ initialize_stype4(unsigned char *buf, const size_t num)
s_ptr->p = i*3+1;
s_ptr->q = i*3+2;
- s_ptr->r = i*5+1;
- s_ptr->s = i*5+2;
- s_ptr->t = i*5+3;
+ s_ptr->r.p=HDmalloc(4*sizeof(unsigned int));
+ s_ptr->r.len=4;
+ for(j=0; j<4; j++)
+ ((unsigned int *)s_ptr->r.p)[j]=i*10+j;
+
+ s_ptr->s = i*5+1;
+ s_ptr->t = i*5+2;
+ s_ptr->u = i*5+3;
}
}
@@ -1086,7 +1125,7 @@ error:
static hid_t
create_stype2(void)
{
- hid_t array_dt1, array_dt2, tid;
+ hid_t array_dt1, array_dt2, vl_tid, tid;
const hsize_t eight = 8, sixteen = 16;
/* Build hdf5 datatypes */
@@ -1094,6 +1133,8 @@ create_stype2(void)
goto error;
if((array_dt2 = H5Tarray_create2(H5T_NATIVE_FLOAT,1, &sixteen)) < 0)
goto error;
+ if((vl_tid = H5Tvlen_create (H5T_NATIVE_UINT)) < 0)
+ goto error;
if((tid = H5Tcreate(H5T_COMPOUND, sizeof(stype2))) < 0 ||
H5Tinsert(tid, "a", HOFFSET(stype2, a), H5T_NATIVE_INT) < 0 ||
@@ -1112,13 +1153,16 @@ create_stype2(void)
H5Tinsert(tid, "n", HOFFSET(stype2, n), H5T_NATIVE_DOUBLE) < 0 ||
H5Tinsert(tid, "o", HOFFSET(stype2, o), H5T_NATIVE_LONG) < 0 ||
H5Tinsert(tid, "p", HOFFSET(stype2, p), H5T_NATIVE_LONG) < 0 ||
- H5Tinsert(tid, "q", HOFFSET(stype2, q), H5T_NATIVE_LONG) < 0)
+ H5Tinsert(tid, "q", HOFFSET(stype2, q), H5T_NATIVE_LONG) < 0 ||
+ H5Tinsert(tid, "r", HOFFSET(stype2, r), vl_tid) < 0)
goto error;
if(H5Tclose(array_dt1) < 0)
goto error;
if(H5Tclose(array_dt2) < 0)
goto error;
+ if(H5Tclose(vl_tid) < 0)
+ goto error;
return tid;
@@ -1188,7 +1232,7 @@ error:
static hid_t
create_stype4(void)
{
- hid_t array_dt1, array_dt2, tid;
+ hid_t array_dt1, array_dt2, vl_tid, tid;
const hsize_t eight = 8, sixteen = 16;
/* Build hdf5 datatypes */
@@ -1196,6 +1240,8 @@ create_stype4(void)
goto error;
if((array_dt2 = H5Tarray_create2(H5T_NATIVE_FLOAT,1, &sixteen)) < 0)
goto error;
+ if((vl_tid = H5Tvlen_create (H5T_NATIVE_UINT)) < 0)
+ goto error;
if((tid = H5Tcreate(H5T_COMPOUND, sizeof(stype4))) < 0 ||
H5Tinsert(tid, "a", HOFFSET(stype4, a), H5T_NATIVE_INT) < 0 ||
@@ -1215,15 +1261,18 @@ create_stype4(void)
H5Tinsert(tid, "o", HOFFSET(stype4, o), H5T_NATIVE_LONG) < 0 ||
H5Tinsert(tid, "p", HOFFSET(stype4, p), H5T_NATIVE_LONG) < 0 ||
H5Tinsert(tid, "q", HOFFSET(stype4, q), H5T_NATIVE_LONG) < 0 ||
- H5Tinsert(tid, "r", HOFFSET(stype4, r), H5T_NATIVE_LLONG) < 0 ||
+ H5Tinsert(tid, "r", HOFFSET(stype4, r), vl_tid) < 0 ||
H5Tinsert(tid, "s", HOFFSET(stype4, s), H5T_NATIVE_LLONG) < 0 ||
- H5Tinsert(tid, "t", HOFFSET(stype4, t), H5T_NATIVE_LLONG) < 0)
+ H5Tinsert(tid, "t", HOFFSET(stype4, t), H5T_NATIVE_LLONG) < 0 ||
+ H5Tinsert(tid, "u", HOFFSET(stype4, u), H5T_NATIVE_LLONG) < 0)
goto error;
if(H5Tclose(array_dt1) < 0)
goto error;
if(H5Tclose(array_dt2) < 0)
goto error;
+ if(H5Tclose(vl_tid) < 0)
+ goto error;
return tid;
@@ -1311,6 +1360,193 @@ error:
/*-------------------------------------------------------------------------
+ * Function: compare_stype2_data
+ *
+ * Purpose: Compare data of stype2.
+ *
+ * Return: Success: 0
+ *
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * Friday, 14 September 2007
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+static int
+compare_stype2_data(void *src_data, void *dst_data, size_t nelmts)
+{
+ stype2 *s_ptr;
+ stype2 *d_ptr;
+ size_t i, j;
+
+ for(i = 0; i < nelmts; i++) {
+ s_ptr = ((stype2*)src_data) + i;
+ d_ptr = ((stype2*)dst_data) + i;
+
+ if (s_ptr->a != d_ptr->a ||
+ s_ptr->b != d_ptr->b ||
+ s_ptr->c[0] != d_ptr->c[0] ||
+ s_ptr->c[1] != d_ptr->c[1] ||
+ s_ptr->c[2] != d_ptr->c[2] ||
+ s_ptr->c[3] != d_ptr->c[3] ||
+ s_ptr->d != d_ptr->d ||
+ s_ptr->e != d_ptr->e ||
+ !FLT_ABS_EQUAL(s_ptr->f, d_ptr->f) ||
+ !FLT_ABS_EQUAL(s_ptr->g, d_ptr->g) ||
+ !FLT_ABS_EQUAL(s_ptr->h[0], d_ptr->h[0]) ||
+ !FLT_ABS_EQUAL(s_ptr->h[1], d_ptr->h[1]) ||
+ !FLT_ABS_EQUAL(s_ptr->i, d_ptr->i) ||
+ !FLT_ABS_EQUAL(s_ptr->j, d_ptr->j) ||
+ !DBL_ABS_EQUAL(s_ptr->k, d_ptr->k) ||
+ !DBL_ABS_EQUAL(s_ptr->l, d_ptr->l) ||
+ !DBL_ABS_EQUAL(s_ptr->m, d_ptr->m) ||
+ !DBL_ABS_EQUAL(s_ptr->n, d_ptr->n) ||
+ s_ptr->o != d_ptr->o ||
+ s_ptr->p != d_ptr->p ||
+ s_ptr->q != d_ptr->q ) {
+
+ H5_FAILED();
+ printf(" i=%d\n", i);
+ printf(" src={a=%d, b=%d, c=[%d,%d,%d,%d,%d,%d,%d,%d], d=%d, e=%d, f=%f, g=%f, h=[%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f], i=%f, j=%f, k=%f, l=%f, m=%f, n=%f, o=%d, p=%d, q=%d}\n",
+ s_ptr->a, s_ptr->b, s_ptr->c[0], s_ptr->c[1], s_ptr->c[2],
+ s_ptr->c[3], s_ptr->c[4], s_ptr->c[5], s_ptr->c[6], s_ptr->c[7],
+ s_ptr->d, s_ptr->e, s_ptr->f, s_ptr->g,s_ptr->h[0],s_ptr->h[1],s_ptr->h[2],
+ s_ptr->h[3],s_ptr->h[4],s_ptr->h[5],s_ptr->h[6],s_ptr->h[7],s_ptr->h[8],
+ s_ptr->h[9],s_ptr->h[10],s_ptr->h[11],s_ptr->h[12],s_ptr->h[13],s_ptr->h[14],
+ s_ptr->h[15], s_ptr->i,s_ptr->j,s_ptr->k,s_ptr->l,s_ptr->m,s_ptr->n,
+ s_ptr->o, s_ptr->p, s_ptr->q);
+ printf(" dst={a=%d, b=%d, c=[%d,%d,%d,%d,%d,%d,%d,%d], d=%d, e=%d, f=%f, g=%f, h=[%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f], i=%f, j=%f, k=%f, l=%f, m=%f, n=%f, o=%d, p=%d, q=%d}\n",
+ d_ptr->a, d_ptr->b, d_ptr->c[0], d_ptr->c[1], d_ptr->c[2],
+ d_ptr->c[3], d_ptr->c[4], d_ptr->c[5], d_ptr->c[6], d_ptr->c[7],
+ d_ptr->d, d_ptr->e, d_ptr->f, d_ptr->g,d_ptr->h[0],d_ptr->h[1],d_ptr->h[2],
+ d_ptr->h[3],d_ptr->h[4],d_ptr->h[5],d_ptr->h[6],d_ptr->h[7],d_ptr->h[8],
+ d_ptr->h[9],d_ptr->h[10],d_ptr->h[11],d_ptr->h[12],d_ptr->h[13],
+ d_ptr->h[14], d_ptr->h[15], d_ptr->i,d_ptr->j,d_ptr->k,d_ptr->l,
+ d_ptr->m,d_ptr->n, d_ptr->o, d_ptr->p, d_ptr->q);
+ goto error;
+ }
+
+ if(s_ptr->r.len!=d_ptr->r.len) {
+ H5_FAILED();
+ printf(" i=%d\n", i);
+ printf("VL data lengths don't match!, src len=%d, dst len=%d\n",(int)s_ptr->r.len,(int)d_ptr->r.len);
+ goto error;
+ } /* end if */
+ for(j=0; j<s_ptr->r.len; j++) {
+ if( ((unsigned int *)s_ptr->r.p)[j] != ((unsigned int *)d_ptr->r.p)[j] ) {
+ H5_FAILED();
+ printf(" i=%d\n", i);
+ printf("VL data values don't match!, src r.p[%d]=%u, dst r.p[%d]=%u\n",(int)j, ((unsigned int *)s_ptr->r.p)[j], (int)j, ((unsigned int *)d_ptr->r.p)[j]);
+ goto error;
+ }
+ }
+ }
+
+ return SUCCEED;
+
+error:
+ return FAIL;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: compare_stype4_data
+ *
+ * Purpose: Compare data of stype4.
+ *
+ * Return: Success: 0
+ *
+ * Failure: negative
+ *
+ * Programmer: Raymond Lu
+ * Friday, 14 September 2007
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+static int
+compare_stype4_data(void *src_data, void *dst_data, size_t nelmts)
+{
+ stype4 *s_ptr;
+ stype4 *d_ptr;
+ size_t i, j;
+
+ for(i = 0; i < nelmts; i++) {
+ s_ptr = ((stype4*)src_data) + i;
+ d_ptr = ((stype4*)dst_data) + i;
+
+ if (s_ptr->a != d_ptr->a ||
+ s_ptr->b != d_ptr->b ||
+ s_ptr->c[0] != d_ptr->c[0] ||
+ s_ptr->c[1] != d_ptr->c[1] ||
+ s_ptr->c[2] != d_ptr->c[2] ||
+ s_ptr->c[3] != d_ptr->c[3] ||
+ s_ptr->d != d_ptr->d ||
+ s_ptr->e != d_ptr->e ||
+ !FLT_ABS_EQUAL(s_ptr->f, d_ptr->f) ||
+ !FLT_ABS_EQUAL(s_ptr->g, d_ptr->g) ||
+ !FLT_ABS_EQUAL(s_ptr->h[0], d_ptr->h[0]) ||
+ !FLT_ABS_EQUAL(s_ptr->h[1], d_ptr->h[1]) ||
+ !FLT_ABS_EQUAL(s_ptr->i, d_ptr->i) ||
+ !FLT_ABS_EQUAL(s_ptr->j, d_ptr->j) ||
+ !DBL_ABS_EQUAL(s_ptr->k, d_ptr->k) ||
+ !DBL_ABS_EQUAL(s_ptr->l, d_ptr->l) ||
+ !DBL_ABS_EQUAL(s_ptr->m, d_ptr->m) ||
+ !DBL_ABS_EQUAL(s_ptr->n, d_ptr->n) ||
+ s_ptr->o != d_ptr->o ||
+ s_ptr->p != d_ptr->p ||
+ s_ptr->q != d_ptr->q ||
+ s_ptr->s != d_ptr->s ||
+ s_ptr->t != d_ptr->t ||
+ s_ptr->u != d_ptr->u ) {
+
+ H5_FAILED();
+ printf(" i=%d\n", i);
+ printf(" src={a=%d, b=%d, c=[%d,%d,%d,%d,%d,%d,%d,%d], d=%d, e=%d, f=%f, g=%f, h=[%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f], i=%f, j=%f, k=%f, l=%f, m=%f, n=%f, o=%d, p=%d, q=%d, s=%ld, t=%ld, u=%ld}\n",
+ s_ptr->a, s_ptr->b, s_ptr->c[0], s_ptr->c[1], s_ptr->c[2],
+ s_ptr->c[3], s_ptr->c[4], s_ptr->c[5], s_ptr->c[6], s_ptr->c[7],
+ s_ptr->d, s_ptr->e, s_ptr->f, s_ptr->g,s_ptr->h[0],s_ptr->h[1],s_ptr->h[2],
+ s_ptr->h[3],s_ptr->h[4],s_ptr->h[5],s_ptr->h[6],s_ptr->h[7],s_ptr->h[8],
+ s_ptr->h[9],s_ptr->h[10],s_ptr->h[11],s_ptr->h[12],s_ptr->h[13],s_ptr->h[14],
+ s_ptr->h[15], s_ptr->i,s_ptr->j,s_ptr->k,s_ptr->l,s_ptr->m,s_ptr->n,
+ s_ptr->o, s_ptr->p, s_ptr->q, s_ptr->s, s_ptr->t, s_ptr->u);
+ printf(" dst={a=%d, b=%d, c=[%d,%d,%d,%d,%d,%d,%d,%d], d=%d, e=%d, f=%f, g=%f, h=[%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f], i=%f, j=%f, k=%f, l=%f, m=%f, n=%f, o=%d, p=%d, q=%d, s=%ld, t=%ld, u=%ld}\n",
+ d_ptr->a, d_ptr->b, d_ptr->c[0], d_ptr->c[1], d_ptr->c[2],
+ d_ptr->c[3], d_ptr->c[4], d_ptr->c[5], d_ptr->c[6], d_ptr->c[7],
+ d_ptr->d, d_ptr->e, d_ptr->f, d_ptr->g,d_ptr->h[0],d_ptr->h[1],d_ptr->h[2],
+ d_ptr->h[3],d_ptr->h[4],d_ptr->h[5],d_ptr->h[6],d_ptr->h[7],d_ptr->h[8],
+ d_ptr->h[9],d_ptr->h[10],d_ptr->h[11],d_ptr->h[12],d_ptr->h[13],
+ d_ptr->h[14], d_ptr->h[15], d_ptr->i,d_ptr->j,d_ptr->k,d_ptr->l,
+ d_ptr->m,d_ptr->n, d_ptr->o, d_ptr->p, d_ptr->q, d_ptr->s, d_ptr->t, d_ptr->u);
+ goto error;
+ }
+
+ if(s_ptr->r.len!=d_ptr->r.len) {
+ H5_FAILED();
+ printf(" i=%d\n", i);
+ printf("VL data lengths don't match!, src len=%d, dst len=%d\n",(int)s_ptr->r.len,(int)d_ptr->r.len);
+ goto error;
+ } /* end if */
+ for(j=0; j<s_ptr->r.len; j++) {
+ if( ((unsigned int *)s_ptr->r.p)[j] != ((unsigned int *)d_ptr->r.p)[j] ) {
+ H5_FAILED();
+ printf(" i=%d\n", i);
+ printf("VL data values don't match!, src r.p[%d]=%u, dst r.p[%d]=%u\n",(int)j, ((unsigned int *)s_ptr->r.p)[j], (int)j, ((unsigned int *)d_ptr->r.p)[j]);
+ goto error;
+ }
+ }
+ }
+
+ return SUCCEED;
+
+error:
+ return FAIL;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: test_hdf5_src_subset
*
* Purpose: Test the optimization of compound data writing, rewriting,
@@ -1345,7 +1581,7 @@ test_hdf5_src_subset(char *filename, hid_t fapl)
hid_t dcpl, dxpl;
hsize_t dims[2] = {NX, NY};
hsize_t chunk_dims[2] = {NX/10, NY/10};
- unsigned char *orig=NULL, *rew_buf=NULL, *rbuf=NULL;
+ void *orig=NULL, *rew_buf=NULL, *rbuf=NULL;
/* Create the file for this test */
if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
@@ -1366,12 +1602,12 @@ test_hdf5_src_subset(char *filename, hid_t fapl)
goto error;
/* Allocate space and initialize data */
- orig = (unsigned char*)malloc(NX * NY * sizeof(stype1));
+ orig = (void*)malloc(NX * NY * sizeof(stype1));
initialize_stype1(orig, (size_t)NX*NY);
- rbuf = (unsigned char*)malloc(NX * NY * sizeof(stype2));
+ rbuf = (void*)malloc(NX * NY * sizeof(stype2));
- rew_buf = (unsigned char*)malloc(NX * NY * sizeof(stype3));
+ rew_buf = (void*)malloc(NX * NY * sizeof(stype3));
initialize_stype3(rew_buf, (size_t)NX*NY);
@@ -1550,7 +1786,7 @@ test_hdf5_dst_subset(char *filename, hid_t fapl)
hid_t dcpl, dxpl;
hsize_t dims[2] = {NX, NY};
hsize_t chunk_dims[2] = {NX/10, NY/10};
- unsigned char *orig=NULL, *rew_buf=NULL, *rbuf=NULL;
+ void *orig=NULL, *rew_buf=NULL, *rbuf=NULL;
/* Create the file for this test */
if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
@@ -1571,12 +1807,12 @@ test_hdf5_dst_subset(char *filename, hid_t fapl)
goto error;
/* Allocate space and initialize data */
- orig = (unsigned char*)malloc(NX * NY * sizeof(stype2));
+ orig = (void*)malloc(NX * NY * sizeof(stype2));
initialize_stype2(orig, (size_t)NX*NY);
- rbuf = (unsigned char*)malloc(NX * NY * sizeof(stype1));
+ rbuf = (void*)malloc(NX * NY * sizeof(stype1));
- rew_buf = (unsigned char*)malloc(NX * NY * sizeof(stype4));
+ rew_buf = (void*)malloc(NX * NY * sizeof(stype4));
initialize_stype4(rew_buf, (size_t)NX*NY);
/* Create dataset creation property list */
@@ -1719,6 +1955,691 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_hdf5_change_dtype_chunked
+ *
+ * Purpose: Test the filter of modifying the datatype of chunked
+ * dataset.
+ *
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 20 Sept 2007
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+#ifdef H5_HAVE_FILTER_DTYPE_MODIFY
+static int
+test_hdf5_change_dtype_chunked(char *filename, hid_t fapl)
+{
+ hid_t file;
+ hid_t rew_tid, src_tid, dst_tid;
+ hid_t dataset;
+ hid_t space, space2, mspace;
+ hid_t fcpl, dcpl, dxpl;
+ hsize_t dims[2] = {NX, NY};
+ hsize_t chunk_dims[2] = {NX/10, NY/10};
+ hsize_t mem_dims[2] = {NX/2, NY};
+ void *orig=NULL, *rew_buf=NULL, *rbuf=NULL;
+ void *rew_half_buf=NULL, *new_rbuf_half=NULL, *orig_rbuf_half=NULL;
+ hsize_t hs_offset[2] = {0,0}; /* Hyperslab offset */
+ const hsize_t hs_size[2] = {NX/2, NY}; /* Hyperslab size */
+ const hsize_t hs_stride[2] = {1,1}; /* Hyperslab stride */
+ const hsize_t hs_count[2] = {1,1}; /* Hyperslab count */
+ unsigned num_indexes;
+ unsigned x;
+
+ if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
+ goto error;
+
+ /* Set up index values for sohm */
+ if(H5Pset_shared_mesg_nindexes(fcpl, TEST_NUM_INDEXES) < 0)
+ goto error;
+
+ for(x=0; x<TEST_NUM_INDEXES; ++x)
+ {
+ if(H5Pset_shared_mesg_index(fcpl, x, test_type_flags[x], test_minsizes[x]) < 0)
+ goto error;
+ }
+
+ if(H5Pset_shared_mesg_phase_change(fcpl, TEST_L2B, TEST_B2L) < 0)
+ goto error;
+
+ /* Create the file for this test */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0)
+ goto error;
+
+ /* Build hdf5 datatypes */
+ if ((src_tid=create_stype2())<0)
+ goto error;
+
+ if ((dst_tid=create_stype1())<0)
+ goto error;
+
+ if ((rew_tid=create_stype4())<0)
+ goto error;
+
+ /* Create the data space */
+ if((space = H5Screate_simple(2, dims, NULL))<0)
+ goto error;
+
+ if((space2 = H5Scopy(space))<0)
+ goto error;
+
+ /* Allocate space and initialize data */
+ orig = (void*)malloc(NX * NY * sizeof(stype2));
+ initialize_stype2(orig, (size_t)NX*NY);
+
+ rbuf = (void*)malloc(NX * NY * sizeof(stype1));
+
+ orig_rbuf_half = (void*)malloc(NX/2 * NY * sizeof(stype2));
+ new_rbuf_half = (void*)malloc(NX/2 * NY * sizeof(stype4));
+
+ rew_half_buf = (void*)malloc((NX/2) * NY * sizeof(stype4));
+ initialize_stype4(rew_half_buf, (size_t)(NX/2)*NY);
+
+ rew_buf = (void*)malloc(NX * NY * sizeof(stype4));
+ initialize_stype4(rew_buf, (size_t)NX*NY);
+
+ /* Create dataset creation property list */
+ if((dcpl = H5Pcreate(H5P_DATASET_CREATE))<0)
+ goto error;
+
+ /*
+ *######################################################################
+ * STEP 1. Write data to a chunked dataset.
+ */
+ TESTING("writing data to a chunked dataset");
+
+ if(H5Pset_dtype_modifiable(dcpl)<0)
+ goto error;
+
+ /* Set chunking */
+ if(H5Pset_chunk(dcpl, 2, chunk_dims)<0)
+ goto error;
+
+ /* Create chunked data set */
+ if((dataset = H5Dcreate2(file, DSET_NAME[3], src_tid, space, H5P_DEFAULT, dcpl, H5P_DEFAULT))<0)
+ goto error;
+
+ /* Write the data to the dataset */
+ if(H5Dwrite(dataset, src_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, orig)<0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 2. Overwrite a half part of the dataset with the new datatype.
+ */
+ TESTING("overwriting half of the data with the new data type");
+
+ /* Create xfer properties to preserve initialized data */
+ if ((dxpl = H5Pcreate (H5P_DATASET_XFER))<0)
+ goto error;
+
+ /* Rewrite chunked data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[3], H5P_DEFAULT))<0)
+ goto error;
+
+ /* Modify the datatype of the chunked dataset now. It should only change
+ * the dataset's datatype, not the actual data. */
+ if(H5Dmodify_dtype(dataset, rew_tid)<0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ /* Rewrite chunked data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[3], H5P_DEFAULT))<0)
+ goto error;
+
+ if (H5Sselect_hyperslab(space, H5S_SELECT_SET, hs_offset, hs_stride, hs_count, hs_size)<0)
+ goto error;
+
+ /* Write the data to the dataset */
+ if(H5Dwrite(dataset, rew_tid, H5S_ALL, space, dxpl, rew_half_buf)<0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 3. Read the original half data and the half data just being
+ * rewritten.
+ */
+ TESTING("reading the half data just being rewritten");
+
+ /* Read the half data just being rewritten */
+ if((dataset = H5Dopen2(file, DSET_NAME[3], H5P_DEFAULT))<0)
+ goto error;
+
+ if(H5Dread(dataset, rew_tid, H5S_ALL, space, dxpl, new_rbuf_half)<0)
+ goto error;
+
+ if(compare_stype4_data(rew_half_buf, new_rbuf_half, (size_t)(NX/2) * NY) < 0)
+ goto error;
+
+ /* Read the original half data */
+ hs_offset[0] = NX / 2;
+
+ if (H5Sselect_hyperslab(space2, H5S_SELECT_SET, hs_offset, hs_stride, hs_count, hs_size)<0)
+ goto error;
+
+ /* Create the data space */
+ if((mspace = H5Screate_simple(2, mem_dims, NULL))<0)
+ goto error;
+
+ if(H5Dread(dataset, src_tid, mspace, space2, dxpl, orig_rbuf_half)<0)
+ goto error;
+
+ if(H5Sclose(mspace) < 0)
+ goto error;
+
+ if(H5Sclose(space2) < 0)
+ goto error;
+
+ if(compare_stype2_data((stype2*)orig + (NX/2)*NY, orig_rbuf_half, (size_t)(NX/2) * NY) < 0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 4. Rewrite the whole data.
+ */
+ TESTING("rewriting data with a subset of original data type");
+
+ /* Create xfer properties to preserve initialized data */
+ if ((dxpl = H5Pcreate (H5P_DATASET_XFER))<0)
+ goto error;
+
+ /* Rewrite chunked data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[3], H5P_DEFAULT))<0)
+ goto error;
+
+ /* Write the data to the dataset */
+ if(H5Dwrite(dataset, rew_tid, H5S_ALL, H5S_ALL, dxpl, rew_buf)<0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 5. Read the whole data.
+ */
+ TESTING("reading data with a subset of original data type");
+
+ /* Check chunked data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[3], H5P_DEFAULT))<0)
+ goto error;
+
+ if(H5Dread(dataset, dst_tid, H5S_ALL, H5S_ALL, dxpl, rbuf)<0)
+ goto error;
+
+ if(compare_data(orig, rbuf, FALSE) < 0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ /* Finishing test and release resources */
+ if(H5Sclose(space) < 0)
+ goto error;
+
+ if(H5Pclose(fcpl) < 0)
+ goto error;
+
+ if(H5Pclose(dcpl) < 0)
+ goto error;
+
+ if(H5Pclose(dxpl) < 0)
+ goto error;
+
+ if(H5Tclose(src_tid)<0)
+ goto error;
+ if(H5Tclose(dst_tid)<0)
+ goto error;
+ if(H5Tclose(rew_tid)<0)
+ goto error;
+ if(H5Fclose(file) < 0)
+ goto error;
+
+ free(orig);
+ free(rbuf);
+ free(new_rbuf_half);
+ free(orig_rbuf_half);
+ free(rew_buf);
+ free(rew_half_buf);
+
+ PASSED();
+ return 0;
+
+error:
+ puts("*** DATASET TESTS FAILED ***");
+ return 1;
+}
+#else /* H5_HAVE_FILTER_DTYPE_MODIFY */
+static int
+test_hdf5_change_dtype(char *filename, hid_t fapl)
+{
+ SKIPPED();
+ puts(" Datatype modification filter not enabled");
+}
+#endif /* H5_HAVE_FILTER_DTYPE_MODIFY */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_hdf5_change_dtype_no_filter
+ *
+ * Purpose: Test the function H5Dmodify_dtype for contiguous dataset
+ * or chunked dataset without the filter.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 20 Sept 2007
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+static int
+test_hdf5_change_dtype_no_filter(char *filename, hid_t fapl, htri_t is_contig)
+{
+ hid_t file;
+ hid_t rew_tid, src_tid, dst_tid;
+ hid_t dataset;
+ hid_t space;
+ hid_t dcpl, dxpl;
+ hsize_t dims[2] = {NX, NY};
+ hsize_t chunk_dims[2] = {NX/10, NY/10};
+ /*hsize_t chunk_dims[2] = {NX, NY};*/
+ void *orig=NULL, *rew_buf=NULL, *rbuf1=NULL, *rbuf2=NULL;
+ unsigned num_indexes;
+ unsigned x;
+
+ /* Create the file for this test */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ goto error;
+
+ /* Build hdf5 datatypes */
+ if ((src_tid=create_stype2())<0)
+ goto error;
+
+ if ((rew_tid=create_stype4())<0)
+ goto error;
+
+ /* Create the data space */
+ if((space = H5Screate_simple(2, dims, NULL))<0)
+ goto error;
+
+ /* Allocate space and initialize data */
+ orig = (void*)malloc(NX * NY * sizeof(stype2));
+ initialize_stype2(orig, (size_t)NX*NY);
+
+ rbuf1 = (void*)malloc(NX * NY * sizeof(stype2));
+
+ rew_buf = (void*)malloc(NX * NY * sizeof(stype4));
+ initialize_stype4(rew_buf, (size_t)NX*NY);
+
+ rbuf2 = (void*)malloc(NX * NY * sizeof(stype4));
+
+ /* Create dataset creation property list */
+ if((dcpl = H5Pcreate(H5P_DATASET_CREATE))<0)
+ goto error;
+
+ /*
+ *######################################################################
+ * STEP 1. Write data to a dataset.
+ */
+ TESTING("writing data to a dataset");
+
+ /* Set chunking if testing chunked dataset */
+ if(!is_contig && H5Pset_chunk(dcpl, 2, chunk_dims)<0)
+ goto error;
+
+ /* Create data set */
+ if((dataset = H5Dcreate2(file, DSET_NAME[2], src_tid, space, H5P_DEFAULT, dcpl, H5P_DEFAULT))<0)
+ goto error;
+
+ /* Write the data to the dataset */
+ if(H5Dwrite(dataset, src_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, orig)<0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 2. Change original data type of the dataset.
+ */
+ TESTING("changing original data type of the dataset");
+
+ /* Rewrite data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[2], H5P_DEFAULT))<0)
+ goto error;
+
+ /* Modify the datatype of the dataset now. It should immediately
+ * change the dataset's datatype and the data. */
+ if(H5Dmodify_dtype(dataset, rew_tid)<0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 3. Read the data into a subset of the original compound type.
+ */
+ TESTING("reading the data of the original data type");
+
+ /* Create xfer properties to preserve initialized data */
+ if ((dxpl = H5Pcreate (H5P_DATASET_XFER))<0)
+ goto error;
+
+ /* Check data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[2], H5P_DEFAULT))<0)
+ goto error;
+
+ if(H5Dread(dataset, src_tid, H5S_ALL, H5S_ALL, dxpl, rbuf1)<0)
+ goto error;
+
+ if(compare_stype2_data(orig, rbuf1, (size_t)NX * NY) < 0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 4. Write the data of the changed data type.
+ */
+ TESTING("writing the data of the changed data type");
+
+ /* Rewrite data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[2], H5P_DEFAULT))<0)
+ goto error;
+
+ /* Write the data to the dataset */
+ if(H5Dwrite(dataset, rew_tid, H5S_ALL, H5S_ALL, dxpl, rew_buf)<0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 5. Read the data of the changed data type.
+ */
+ TESTING("reading the data of the changed data type");
+
+ /* Check data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[2], H5P_DEFAULT))<0)
+ goto error;
+
+ if(H5Dread(dataset, rew_tid, H5S_ALL, H5S_ALL, dxpl, rbuf2)<0)
+ goto error;
+
+ if(compare_stype4_data(rew_buf, rbuf2, (size_t)NX * NY) < 0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ /* Finishing test and release resources */
+ if(H5Sclose(space) < 0)
+ goto error;
+
+ if(H5Pclose(dcpl) < 0)
+ goto error;
+
+ if(H5Pclose(dxpl) < 0)
+ goto error;
+
+ if(H5Tclose(src_tid)<0)
+ goto error;
+ if(H5Tclose(rew_tid)<0)
+ goto error;
+ if(H5Fclose(file) < 0)
+ goto error;
+
+ free(orig);
+ free(rbuf1);
+ free(rbuf2);
+ free(rew_buf);
+
+ PASSED();
+ return 0;
+
+error:
+ puts("*** DATASET TESTS FAILED ***");
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_hdf5_change_dtype_compact
+ *
+ * Purpose: Test the function H5Dmodify_dtype for compact dataset.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Raymond Lu
+ * 20 Sept 2007
+ *
+ * Modifications:
+ *-------------------------------------------------------------------------
+ */
+static int
+test_hdf5_change_dtype_compact(char *filename, hid_t fapl)
+{
+ hid_t file;
+ hid_t rew_tid, src_tid, dst_tid;
+ hid_t dataset;
+ hid_t space;
+ hid_t dcpl, dxpl;
+ hsize_t dims[2] = {COMP_NX, COMP_NY};
+ void *orig=NULL, *rew_buf=NULL, *rbuf1=NULL, *rbuf2=NULL;
+ unsigned num_indexes;
+ unsigned x;
+
+ /* Create the file for this test */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ goto error;
+
+ /* Build hdf5 datatypes */
+ if ((src_tid=create_stype2())<0)
+ goto error;
+
+ if ((rew_tid=create_stype4())<0)
+ goto error;
+
+ /* Create the data space */
+ if((space = H5Screate_simple(2, dims, NULL))<0)
+ goto error;
+
+ /* Allocate space and initialize data */
+ orig = (void*)malloc(COMP_NX * COMP_NY * sizeof(stype2));
+ initialize_stype2(orig, (size_t)COMP_NX*COMP_NY);
+
+ rbuf1 = (void*)malloc(COMP_NX * COMP_NY * sizeof(stype2));
+
+ rew_buf = (void*)malloc(COMP_NX * COMP_NY * sizeof(stype4));
+ initialize_stype4(rew_buf, (size_t)COMP_NX*COMP_NY);
+
+ rbuf2 = (void*)malloc(COMP_NX * COMP_NY * sizeof(stype4));
+
+ /* Create property list for compact dataset creation */
+ if((dcpl = H5Pcreate(H5P_DATASET_CREATE))<0)
+ goto error;
+
+ if(H5Pset_layout(dcpl, H5D_COMPACT) < 0)
+ goto error;
+
+ if(H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_EARLY) < 0)
+ goto error;
+
+ /*
+ *######################################################################
+ * STEP 1. Write data to a compact dataset.
+ */
+ TESTING("writing data to a compact dataset");
+
+ /* Create compact data set */
+ if((dataset = H5Dcreate2(file, DSET_NAME[4], src_tid, space, H5P_DEFAULT, dcpl, H5P_DEFAULT))<0)
+ goto error;
+
+ /* Write the data to the dataset */
+ if(H5Dwrite(dataset, src_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, orig)<0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 2. Change original data type of the dataset.
+ */
+ TESTING("changing original data type of the dataset");
+
+ /* Rewrite compact data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[4], H5P_DEFAULT))<0)
+ goto error;
+
+ /* Modify the datatype of the compact dataset now. It should immediately
+ * change the dataset's datatype and the data. */
+ if(H5Dmodify_dtype(dataset, rew_tid)<0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 3. Read the data into a subset of the original compound type.
+ */
+ TESTING("reading the data of the original data type");
+
+ /* Create xfer properties */
+ if ((dxpl = H5Pcreate (H5P_DATASET_XFER))<0)
+ goto error;
+
+ /* Check compact data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[4], H5P_DEFAULT))<0)
+ goto error;
+
+ if(H5Dread(dataset, src_tid, H5S_ALL, H5S_ALL, dxpl, rbuf1)<0)
+ goto error;
+
+ if(compare_stype2_data(orig, rbuf1, (size_t)COMP_NX * COMP_NY) < 0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 4. Write the data of the changed data type.
+ */
+ TESTING("writing the data of the changed data type");
+
+ /* Rewrite compact data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[4], H5P_DEFAULT))<0)
+ goto error;
+
+ /* Write the data to the dataset */
+ if(H5Dwrite(dataset, rew_tid, H5S_ALL, H5S_ALL, dxpl, rew_buf)<0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ PASSED();
+
+ /*
+ *######################################################################
+ * STEP 5. Read the data of the changed data type.
+ */
+ TESTING("reading the data of the changed data type");
+
+ /* Check compact data set */
+ if((dataset = H5Dopen2(file, DSET_NAME[4], H5P_DEFAULT))<0)
+ goto error;
+
+ if(H5Dread(dataset, rew_tid, H5S_ALL, H5S_ALL, dxpl, rbuf2)<0)
+ goto error;
+
+ if(compare_stype4_data(rew_buf, rbuf2, (size_t)COMP_NX * COMP_NY) < 0)
+ goto error;
+
+ if(H5Dclose(dataset) < 0)
+ goto error;
+
+ /* Finishing test and release resources */
+ if(H5Sclose(space) < 0)
+ goto error;
+
+ if(H5Pclose(dcpl) < 0)
+ goto error;
+
+ if(H5Pclose(dxpl) < 0)
+ goto error;
+
+ if(H5Tclose(src_tid)<0)
+ goto error;
+ if(H5Tclose(rew_tid)<0)
+ goto error;
+ if(H5Fclose(file) < 0)
+ goto error;
+
+ free(orig);
+ free(rbuf1);
+ free(rbuf2);
+ free(rew_buf);
+
+ PASSED();
+ return 0;
+
+error:
+ puts("*** DATASET TESTS FAILED ***");
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Test different cases of I/O for compound data and the
@@ -1732,6 +2653,12 @@ error:
* Friday, 15 June 2007
*
* Modifications:
+ * Raymond Lu
+ * 20 Sept 2007
+ * Added the tests for the filter of datatype modification
+ * and H5Dmodify_dtype, for chunked, contiguous, and compact
+ * datasets.
+ *
*-------------------------------------------------------------------------
*/
int
@@ -1755,9 +2682,8 @@ main (int argc, char *argv[])
/* Create the file */
fapl_id = h5_fileaccess();
- h5_fixname(FILENAME[0], fapl_id, fname, sizeof(fname));
-
puts("Testing compound dataset:");
+ h5_fixname(FILENAME[0], fapl_id, fname, sizeof(fname));
nerrors += test_compound(fname, fapl_id);
puts("Testing the optimization of when the source type is a subset of the dest:");
@@ -1768,6 +2694,22 @@ main (int argc, char *argv[])
h5_fixname(FILENAME[2], fapl_id, fname, sizeof(fname));
nerrors += test_hdf5_dst_subset(fname, fapl_id);
+ puts("Testing the filter for modifying datatype of chunked dataset:");
+ h5_fixname(FILENAME[3], fapl_id, fname, sizeof(fname));
+ nerrors += test_hdf5_change_dtype_chunked(fname, fapl_id);
+
+ puts("Testing modifying datatype of chunked dataset with no filter:");
+ h5_fixname(FILENAME[4], fapl_id, fname, sizeof(fname));
+ nerrors += test_hdf5_change_dtype_no_filter(fname, fapl_id, FALSE);
+
+ puts("Testing modifying datatype of contiguous dataset:");
+ h5_fixname(FILENAME[5], fapl_id, fname, sizeof(fname));
+ nerrors += test_hdf5_change_dtype_no_filter(fname, fapl_id, TRUE);
+
+ puts("Testing modifying datatype of compact dataset:");
+ h5_fixname(FILENAME[6], fapl_id, fname, sizeof(fname));
+ nerrors += test_hdf5_change_dtype_compact(fname, fapl_id);
+
if (nerrors) {
printf("***** %u FAILURE%s! *****\n",
nerrors, 1==nerrors?"":"S");
diff --git a/test/dsets.c b/test/dsets.c
index bf58018..d5949eb 100644
--- a/test/dsets.c
+++ b/test/dsets.c
@@ -63,6 +63,8 @@ const char *FILENAME[] = {
#define DSET_FLETCHER32_NAME "fletcher32"
#define DSET_FLETCHER32_NAME_2 "fletcher32_2"
#define DSET_FLETCHER32_NAME_3 "fletcher32_3"
+#define DSET_DTYPE_MODIFY_NAME "dtype_modify"
+#define DSET_SHUF_DEF_DTMOD_NAME "dtype_modify+shuffle+deflate"
#define DSET_SHUF_DEF_FLET_NAME "shuffle+deflate+fletcher32"
#define DSET_SHUF_DEF_FLET_NAME_2 "shuffle+deflate+fletcher32_2"
#define DSET_SHUF_SZIP_FLET_NAME "shuffle+szip+fletcher32"
@@ -101,12 +103,15 @@ const char *FILENAME[] = {
#define H5Z_FILTER_BOGUS 305
#define H5Z_FILTER_CORRUPT 306
#define H5Z_FILTER_BOGUS2 307
+#define H5Z_FILTER_BOGUS3 308
/* Flags for testing filters */
#define DISABLE_FLETCHER32 0
#define ENABLE_FLETCHER32 1
#define DATA_CORRUPTED 1
#define DATA_NOT_CORRUPTED 0
+#define CHANGE_DTYPE 1
+#define DONT_CHANGE_DTYPE 0
/* Parameters for the "set local" test */
#define BOGUS2_PERM_NPARMS 2 /* Number of "permanent" parameters */
@@ -122,10 +127,15 @@ const char *FILENAME[] = {
/* Parameters for internal filter test */
#define FILTER_CHUNK_DIM1 2
#define FILTER_CHUNK_DIM2 25
-#define FILTER_HS_OFFSET1 7
+/*#define FILTER_HS_OFFSET1 7
#define FILTER_HS_OFFSET2 30
#define FILTER_HS_SIZE1 4
-#define FILTER_HS_SIZE2 50
+#define FILTER_HS_SIZE2 50*/
+#define FILTER_HS_OFFSET1 1
+#define FILTER_HS_OFFSET2 12
+#define FILTER_HS_SIZE1 1
+#define FILTER_HS_SIZE2 38
+
/* Names for noencoder test */
#define NOENCODER_FILENAME "noencoder.h5"
@@ -145,16 +155,18 @@ const char *FILENAME[] = {
#define RC_FILENAME "random_chunks.h5"
/* Shared global arrays */
-#define DSET_DIM1 100
-#define DSET_DIM2 200
+#define DSET_DIM1 4
+#define DSET_DIM2 50
int points[DSET_DIM1][DSET_DIM2], check[DSET_DIM1][DSET_DIM2];
double points_dbl[DSET_DIM1][DSET_DIM2], check_dbl[DSET_DIM1][DSET_DIM2];
/* Local prototypes for filter functions */
static size_t filter_bogus(unsigned int flags, size_t cd_nelmts,
const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
-static herr_t can_apply_bogus(hid_t dcpl_id, hid_t type_id, hid_t space_id);
-static herr_t set_local_bogus2(hid_t dcpl_id, hid_t type_id, hid_t space_id);
+static herr_t can_apply_bogus(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t file_id);
+static herr_t set_local_bogus2(hid_t dcpl_id, hid_t type_id, hid_t space_id,
+ hid_t file_id);
static size_t filter_bogus2(unsigned int flags, size_t cd_nelmts,
const unsigned int *cd_values, size_t nbytes, size_t *buf_size, void **buf);
static size_t filter_corrupt(unsigned int flags, size_t cd_nelmts,
@@ -986,6 +998,7 @@ const H5Z_class_t H5Z_BOGUS[1] = {{
"bogus", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
filter_bogus, /* The actual filter function */
}};
@@ -1007,7 +1020,8 @@ const H5Z_class_t H5Z_BOGUS[1] = {{
*-------------------------------------------------------------------------
*/
static herr_t
-can_apply_bogus(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id)
+can_apply_bogus(hid_t UNUSED dcpl_id, hid_t type_id, hid_t UNUSED space_id,
+ hid_t UNUSED file_id)
{
if(H5Tequal(type_id,H5T_NATIVE_DOUBLE))
return 0;
@@ -1059,7 +1073,8 @@ filter_bogus(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
*-------------------------------------------------------------------------
*/
static herr_t
-set_local_bogus2(hid_t dcpl_id, hid_t type_id, hid_t UNUSED space_id)
+set_local_bogus2(hid_t dcpl_id, hid_t type_id, hid_t UNUSED space_id,
+ hid_t UNUSED file_id)
{
unsigned add_on=0; /* Value to add to data going through */
unsigned flags; /* Filter flags */
@@ -1160,6 +1175,7 @@ const H5Z_class_t H5Z_CORRUPT[1] = {{
"corrupt", /* Filter name for debugging */
NULL, /* The "can apply" callback */
NULL, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
filter_corrupt, /* The actual filter function */
}};
@@ -1296,7 +1312,7 @@ filter_cb_fail(H5Z_filter_t filter, void UNUSED *buf, size_t UNUSED buf_size,
*/
static herr_t
test_filter_internal(hid_t fid, const char *name, hid_t dcpl, int if_fletcher32,
- int corrupted, hsize_t *dset_size)
+ int corrupted, int change_dtype, hsize_t *dset_size)
{
hid_t dataset; /* Dataset ID */
hid_t dxpl; /* Dataset xfer property list ID */
@@ -1442,51 +1458,88 @@ test_filter_internal(hid_t fid, const char *name, hid_t dcpl, int if_fletcher32,
*/
TESTING(" filters (modify)");
- for(i=0; i<size[0]; i++) {
- for(j=0; j<size[1]/2; j++) {
- points[i][j] = (int)HDrandom ();
- }
- }
- if(H5Dwrite (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, points) < 0)
- TEST_ERROR;
+ /* If the datatype modification filter is used, change the data type of
+ * the dataset and rewrite some data of a different type.
+ */
+ if(change_dtype) {
+ if(H5Dmodify_dtype(dataset, H5T_NATIVE_DOUBLE)<0)
+ TEST_ERROR;
- if(corrupted) {
- /* Default behavior is failure when data is corrupted. */
- /* (Use the "write" DXPL in order to make certain corruption is seen) */
- H5E_BEGIN_TRY {
- status=H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, check);
- } H5E_END_TRY;
- if(status>=0) TEST_ERROR;
+ for (i=0; i<size[0]; i++) {
+ for (j=0; j<size[1]; j++) {
+ points_dbl[i][j] = (double)(i+j+1)/1.7;
+ }
+ }
- /* Callback decides to continue inspite data is corrupted. */
- if(H5Pset_filter_callback(dxpl, filter_cb_cont, NULL) < 0) TEST_ERROR;
- if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check) < 0)
- TEST_ERROR;
+ if (H5Dwrite (dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, write_dxpl, points_dbl)<0)
+ TEST_ERROR;
- /* Callback decides to fail when data is corrupted. */
- if(H5Pset_filter_callback(write_dxpl, filter_cb_fail, NULL) < 0) TEST_ERROR;
- /* (Use the "write" DXPL in order to make certain corruption is seen) */
- H5E_BEGIN_TRY {
- status=H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, check);
- } H5E_END_TRY;
- if(status>=0) TEST_ERROR;
- } else {
/* Read the dataset back and check it */
- if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check) < 0)
+ if (H5Dread(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, dxpl, check_dbl)<0)
TEST_ERROR;
/* Check that the values read are the same as the values written */
- for(i=0; i<size[0]; i++) {
- for(j=0; j<size[1]; j++) {
- if(points[i][j] != check[i][j]) {
- H5_FAILED();
- printf(" Read different values than written.\n");
- printf(" At index %lu,%lu\n",
- (unsigned long)i, (unsigned long)j);
- goto error;
+ for (i=0; i<size[0]; i++) {
+ for (j=0; j<size[1]; j++) {
+ /* If the difference between two values is greater than 0.001%, they're
+ * considered not equal. */
+ if(!DBL_REL_EQUAL(points_dbl[i][j],check_dbl[i][j],0.00001)) {
+ H5_FAILED();
+ printf(" Read different values than written.\n");
+ printf(" At index %lu,%lu: points_dbl=%f,check_dbl=%f\n",
+ (unsigned long)i, (unsigned long)j, points_dbl[i][j],check_dbl[i][j]);
+ /*goto error;*/
}
}
}
+ } else {
+ for (i=0; i<size[0]; i++) {
+ for (j=0; j<size[1]/2; j++) {
+ points[i][j] = (int)HDrandom ();
+ }
+ }
+
+ if (H5Dwrite (dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, points)<0)
+ TEST_ERROR;
+
+ if(corrupted) {
+ /* Default behavior is failure when data is corrupted. */
+ /* (Use the "write" DXPL in order to make certain corruption is seen) */
+ H5E_BEGIN_TRY {
+ status=H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, check);
+ } H5E_END_TRY;
+ if(status>=0) TEST_ERROR;
+
+ /* Callback decides to continue inspite data is corrupted. */
+ if(H5Pset_filter_callback(dxpl, filter_cb_cont, NULL)<0) TEST_ERROR;
+ if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check)<0)
+ TEST_ERROR;
+
+ /* Callback decides to fail when data is corrupted. */
+ if(H5Pset_filter_callback(write_dxpl, filter_cb_fail, NULL)<0) TEST_ERROR;
+ /* (Use the "write" DXPL in order to make certain corruption is seen) */
+ H5E_BEGIN_TRY {
+ status=H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, check);
+ } H5E_END_TRY;
+ if(status>=0) TEST_ERROR;
+ } else {
+ /* Read the dataset back and check it */
+ if (H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check)<0)
+ TEST_ERROR;
+
+ /* Check that the values read are the same as the values written */
+ for (i=0; i<size[0]; i++) {
+ for (j=0; j<size[1]; j++) {
+ if (points[i][j] != check[i][j]) {
+ H5_FAILED();
+ printf(" Read different values than written.\n");
+ printf(" At index %lu,%lu\n",
+ (unsigned long)i, (unsigned long)j);
+ goto error;
+ }
+ }
+ }
+ }
}
if((*dset_size=H5Dget_storage_size(dataset))==0) TEST_ERROR;
@@ -1503,47 +1556,65 @@ test_filter_internal(hid_t fid, const char *name, hid_t dcpl, int if_fletcher32,
if(H5Dclose(dataset) < 0) TEST_ERROR;
if((dataset = H5Dopen2(fid, name, H5P_DEFAULT)) < 0) TEST_ERROR;
- if(corrupted) {
- /* Default behavior is failure when data is corrupted. */
- /* (Use the "write" DXPL in order to make certain corruption is seen) */
- H5E_BEGIN_TRY {
- status = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, check);
- } H5E_END_TRY;
- if(status >= 0) TEST_ERROR;
-
- /* Callback decides to continue inspite data is corrupted. */
- if(H5Pset_filter_callback(dxpl, filter_cb_cont, NULL) < 0) TEST_ERROR;
- if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check) < 0)
- TEST_ERROR;
-
- /* Callback decides to fail when data is corrupted. */
- if(H5Pset_filter_callback(write_dxpl, filter_cb_fail, NULL) < 0) TEST_ERROR;
-
- /* (Use the "write" DXPL in order to make certain corruption is seen) */
- H5E_BEGIN_TRY {
- status = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, check);
- } H5E_END_TRY;
- if(status >= 0) TEST_ERROR;
- } /* end if */
- else {
- if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check) < 0)
- TEST_ERROR;
+ if(change_dtype) {
+ if (H5Dread(dataset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, dxpl, check_dbl)<0)
+ TEST_ERROR;
/* Check that the values read are the same as the values written */
- for(i = 0; i < size[0]; i++)
- for(j = 0; j < size[1]; j++)
- if(points[i][j] != check[i][j]) {
+ for (i=0; i<size[0]; i++) {
+ for (j=0; j<size[1]; j++) {
+ /* If the difference between two values is greater than 0.001%, they're
+ * considered not equal. */
+ if(!DBL_REL_EQUAL(points_dbl[i][j],check_dbl[i][j],0.00001)) {
H5_FAILED();
printf(" Read different values than written.\n");
printf(" At index %lu,%lu\n",
(unsigned long)i, (unsigned long)j);
goto error;
- } /* end if */
- } /* end else */
+ }
+ }
+ }
+ } else {
+ if(corrupted) {
+ /* Default behavior is failure when data is corrupted. */
+ /* (Use the "write" DXPL in order to make certain corruption is seen) */
+ H5E_BEGIN_TRY {
+ status=H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, check);
+ } H5E_END_TRY;
+ if(status>=0) TEST_ERROR;
+
+ /* Callback decides to continue inspite data is corrupted. */
+ if(H5Pset_filter_callback(dxpl, filter_cb_cont, NULL)<0) TEST_ERROR;
+ if(H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check)<0)
+ TEST_ERROR;
+ /* Callback decides to fail when data is corrupted. */
+ if(H5Pset_filter_callback(write_dxpl, filter_cb_fail, NULL)<0) TEST_ERROR;
+ /* (Use the "write" DXPL in order to make certain corruption is seen) */
+ H5E_BEGIN_TRY {
+ status=H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, write_dxpl, check);
+ } H5E_END_TRY;
+ if(status>=0) TEST_ERROR;
+ } else {
+ if (H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl, check)<0)
+ TEST_ERROR;
+
+ /* Check that the values read are the same as the values written */
+ for (i=0; i<size[0]; i++) {
+ for (j=0; j<size[1]; j++) {
+ if (points[i][j] != check[i][j]) {
+ H5_FAILED();
+ printf(" Read different values than written.\n");
+ printf(" At index %lu,%lu\n",
+ (unsigned long)i, (unsigned long)j);
+ goto error;
+ }
+ }
+ }
+ }
+ }
PASSED();
-
/*----------------------------------------------------------------------
* STEP 6: Test partial I/O by writing to and then reading from a
* hyperslab of the dataset. The hyperslab does not line up on chunk
@@ -1611,6 +1682,7 @@ test_filter_internal(hid_t fid, const char *name, hid_t dcpl, int if_fletcher32,
/* Get the storage size of the dataset */
if((*dset_size=H5Dget_storage_size(dataset))==0) goto error;
+
/* Clean up objects used for this test */
if(H5Dclose (dataset) < 0) goto error;
if(H5Sclose (sid) < 0) goto error;
@@ -1885,7 +1957,11 @@ UNUSED
hsize_t shuffle_size; /* Size of dataset with shuffle filter */
#endif /* H5_HAVE_FILTER_SHUFFLE */
-#if(defined H5_HAVE_FILTER_DEFLATE | defined H5_HAVE_FILTER_SZIP) && defined H5_HAVE_FILTER_SHUFFLE && defined H5_HAVE_FILTER_FLETCHER32
+#ifdef H5_HAVE_FILTER_DTYPE_MODIFY
+ hsize_t dtype_modify_size; /* Size of dataset with datatype modification filter */
+#endif /* H5_HAVE_FILTER_DTYPE_MODIFY */
+
+#if (defined H5_HAVE_FILTER_DEFLATE | defined H5_HAVE_FILTER_SZIP) && defined H5_HAVE_FILTER_SHUFFLE && defined H5_HAVE_FILTER_FLETCHER32
hsize_t combo_size; /* Size of dataset with shuffle+deflate filter */
#endif /* H5_HAVE_FILTER_DEFLATE && H5_HAVE_FILTER_SHUFFLE && H5_HAVE_FILTER_FLETCHER32 */
@@ -1900,9 +1976,9 @@ UNUSED
if((dc = H5Pcreate(H5P_DATASET_CREATE)) < 0) goto error;
if(H5Pset_chunk (dc, 2, chunk_size) < 0) goto error;
if(H5Zregister (H5Z_BOGUS) < 0) goto error;
- if(H5Pset_filter(dc, H5Z_FILTER_BOGUS, 0, (size_t)0, NULL) < 0) goto error;
+ if(H5Pset_filter(dc, H5Z_FILTER_BOGUS, H5Z_FLAG_MANDATORY, (size_t)0, NULL) < 0) goto error;
- if(test_filter_internal(file,DSET_BOGUS_NAME,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,&null_size) < 0) goto error;
+ if(test_filter_internal(file,DSET_BOGUS_NAME,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&null_size)<0) goto error;
/* Clean up objects used for this test */
if(H5Pclose (dc) < 0) goto error;
@@ -1918,7 +1994,8 @@ UNUSED
if(H5Pset_filter(dc, H5Z_FILTER_FLETCHER32, 0, (size_t)0, NULL) < 0) goto error;
/* Enable checksum during read */
- if(test_filter_internal(file,DSET_FLETCHER32_NAME,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,&fletcher32_size) < 0) goto error;
+ if(test_filter_internal(file,DSET_FLETCHER32_NAME,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&fletcher32_size)<0) goto error;
+
if(fletcher32_size<=null_size) {
H5_FAILED();
puts(" Size after checksumming is incorrect.");
@@ -1927,7 +2004,8 @@ UNUSED
/* Disable checksum during read */
puts("Testing Fletcher32 checksum(disabled for read)");
- if(test_filter_internal(file,DSET_FLETCHER32_NAME_2,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,&fletcher32_size) < 0) goto error;
+ if(test_filter_internal(file,DSET_FLETCHER32_NAME_2,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&fletcher32_size)<0) goto error;
+
if(fletcher32_size<=null_size) {
H5_FAILED();
puts(" Size after checksumming is incorrect.");
@@ -1944,7 +2022,9 @@ UNUSED
* the way this test is conducted. -slu 2007/7/20 */
if(H5Zregister (H5Z_CORRUPT) < 0) goto error;
if(H5Pset_filter(dc, H5Z_FILTER_CORRUPT, 0, (size_t)3, data_corrupt) < 0) goto error;
- if(test_filter_internal(file,DSET_FLETCHER32_NAME_3,dc,DISABLE_FLETCHER32,DATA_CORRUPTED,&fletcher32_size) < 0) goto error;
+
+ if(test_filter_internal(file,DSET_FLETCHER32_NAME_3,dc,DISABLE_FLETCHER32,DATA_CORRUPTED,DONT_CHANGE_DTYPE,&fletcher32_size)<0) goto error;
+
if(fletcher32_size<=null_size) {
H5_FAILED();
puts(" Size after checksumming is incorrect.");
@@ -1970,7 +2050,8 @@ UNUSED
if(H5Pset_chunk (dc, 2, chunk_size) < 0) goto error;
if(H5Pset_deflate (dc, 6) < 0) goto error;
- if(test_filter_internal(file,DSET_DEFLATE_NAME,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,&deflate_size) < 0) goto error;
+ if(test_filter_internal(file,DSET_DEFLATE_NAME,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&deflate_size)<0) goto error;
+
/* Clean up objects used for this test */
if(H5Pclose (dc) < 0) goto error;
#else /* H5_HAVE_FILTER_DEFLATE */
@@ -1990,9 +2071,10 @@ UNUSED
if(H5Pset_chunk (dc, 2, chunk_size) < 0) goto error;
puts("");
- if(H5Pset_szip(dc, szip_options_mask, szip_pixels_per_block) < 0) goto error;
- if(test_filter_internal(file,DSET_SZIP_NAME,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,&szip_size) < 0) goto error;
- if(H5Pclose (dc) < 0) goto error;
+
+ if (H5Pset_szip(dc, szip_options_mask, szip_pixels_per_block)<0) goto error;
+ if(test_filter_internal(file,DSET_SZIP_NAME,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&szip_size)<0) goto error;
+ if (H5Pclose (dc)<0) goto error;
} else {
SKIPPED();
}
@@ -2022,7 +2104,8 @@ UNUSED
if(H5Pset_chunk (dc, 2, chunk_size) < 0) goto error;
if(H5Pset_shuffle (dc) < 0) goto error;
- if(test_filter_internal(file,DSET_SHUFFLE_NAME,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,&shuffle_size) < 0) goto error;
+ if(test_filter_internal(file,DSET_SHUFFLE_NAME,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&shuffle_size)<0) goto error;
+
if(shuffle_size!=null_size) {
H5_FAILED();
puts(" Shuffled size not the same as uncompressed size.");
@@ -2038,7 +2121,49 @@ UNUSED
#endif /* H5_HAVE_FILTER_SHUFFLE */
/*----------------------------------------------------------
- * STEP 5: Test shuffle + deflate + checksum in any order.
+ * STEP 5: Test datatype modification by itself.
+ *----------------------------------------------------------
+ */
+#ifdef H5_HAVE_FILTER_DTYPE_MODIFY
+ puts("Testing datatype modification filter");
+ if((dc = H5Pcreate(H5P_DATASET_CREATE))<0) goto error;
+ if (H5Pset_chunk (dc, 2, chunk_size)<0) goto error;
+ if (H5Pset_dtype_modifiable (dc)<0) goto error;
+
+ if(test_filter_internal(file,DSET_DTYPE_MODIFY_NAME,dc,DISABLE_FLETCHER32,DATA_NOT_CORRUPTED,CHANGE_DTYPE,&dtype_modify_size)<0) goto error;
+
+ /* Clean up objects used for this test */
+ if (H5Pclose (dc)<0) goto error;
+#else /* H5_HAVE_FILTER_DTYPE_MODIFY */
+ TESTING("datatype modification filter");
+ SKIPPED();
+ puts(" Datatype modification filter not enabled");
+#endif /* H5_HAVE_FILTER_DTYPE_MODIFY */
+
+ /*----------------------------------------------------------
+ * STEP 6: Test shuffle + deflate + dtype modification.
+ *----------------------------------------------------------
+ */
+#if defined H5_HAVE_FILTER_DEFLATE && defined H5_HAVE_FILTER_SHUFFLE && defined H5_HAVE_FILTER_DTYPE_MODIFY
+ puts("Testing dtype modify+shuffle+deflate filters(dtype modify first)");
+ if((dc = H5Pcreate(H5P_DATASET_CREATE))<0) goto error;
+ if (H5Pset_chunk (dc, 2, chunk_size)<0) goto error;
+ if (H5Pset_dtype_modifiable (dc)<0) goto error;
+ if (H5Pset_shuffle (dc)<0) goto error;
+ if (H5Pset_deflate (dc, 6)<0) goto error;
+
+ if(test_filter_internal(file,DSET_SHUF_DEF_DTMOD_NAME,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,CHANGE_DTYPE,&combo_size)<0) goto error;
+
+ /* Clean up objects used for this test */
+ if (H5Pclose (dc)<0) goto error;
+#else /* H5_HAVE_FILTER_DEFLATE && H5_HAVE_FILTER_SHUFFLE && H5_HAVE_FILTER_DTYPE_MODIFY */
+ TESTING("dtype modify+shuffle+deflate filters");
+ SKIPPED();
+ puts(" Deflate, shuffle, or dtype modify checksum filter not enabled");
+#endif /* H5_HAVE_FILTER_DEFLATE && H5_HAVE_FILTER_SHUFFLE && H5_HAVE_FILTER_DTYPE_MODIFY */
+
+ /*----------------------------------------------------------
+ * STEP 7: Test shuffle + deflate + checksum in any order.
*----------------------------------------------------------
*/
#if defined H5_HAVE_FILTER_DEFLATE && defined H5_HAVE_FILTER_SHUFFLE && defined H5_HAVE_FILTER_FLETCHER32
@@ -2049,7 +2174,7 @@ UNUSED
if(H5Pset_shuffle (dc) < 0) goto error;
if(H5Pset_deflate (dc, 6) < 0) goto error;
- if(test_filter_internal(file,DSET_SHUF_DEF_FLET_NAME,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,&combo_size) < 0) goto error;
+ if(test_filter_internal(file,DSET_SHUF_DEF_FLET_NAME,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&combo_size)<0) goto error;
/* Clean up objects used for this test */
if(H5Pclose (dc) < 0) goto error;
@@ -2061,7 +2186,7 @@ UNUSED
if(H5Pset_deflate (dc, 6) < 0) goto error;
if(H5Pset_fletcher32 (dc) < 0) goto error;
- if(test_filter_internal(file,DSET_SHUF_DEF_FLET_NAME_2,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,&combo_size) < 0) goto error;
+ if(test_filter_internal(file,DSET_SHUF_DEF_FLET_NAME_2,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&combo_size)<0) goto error;
/* Clean up objects used for this test */
if(H5Pclose (dc) < 0) goto error;
@@ -2072,7 +2197,7 @@ UNUSED
#endif /* H5_HAVE_FILTER_DEFLATE && H5_HAVE_FILTER_SHUFFLE && H5_HAVE_FILTER_FLETCHER32 */
/*----------------------------------------------------------
- * STEP 6: Test shuffle + szip + checksum in any order.
+ * STEP 8: Test shuffle + szip + checksum in any order.
*----------------------------------------------------------
*/
#if defined H5_HAVE_FILTER_SZIP && defined H5_HAVE_FILTER_SHUFFLE && defined H5_HAVE_FILTER_FLETCHER32
@@ -2086,8 +2211,9 @@ UNUSED
/* Make sure encoding is enabled */
if( h5_szip_can_encode() == 1) {
puts("");
- if(H5Pset_szip(dc, szip_options_mask, szip_pixels_per_block) < 0) goto error;
- if(test_filter_internal(file,DSET_SHUF_SZIP_FLET_NAME,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,&combo_size) < 0) goto error;
+
+ if (H5Pset_szip(dc, szip_options_mask, szip_pixels_per_block)<0) goto error;
+ if(test_filter_internal(file,DSET_SHUF_SZIP_FLET_NAME,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&combo_size)<0) goto error;
} else {
SKIPPED();
}
@@ -2115,7 +2241,7 @@ UNUSED
if(H5Pset_szip(dc, szip_options_mask, szip_pixels_per_block) < 0) goto error;
if(H5Pset_fletcher32 (dc) < 0) goto error;
- if(test_filter_internal(file,DSET_SHUF_SZIP_FLET_NAME_2,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,&combo_size) < 0) goto error;
+ if(test_filter_internal(file,DSET_SHUF_SZIP_FLET_NAME_2,dc,ENABLE_FLETCHER32,DATA_NOT_CORRUPTED,DONT_CHANGE_DTYPE,&combo_size)<0) goto error;
/* Clean up objects used for this test */
if(H5Pclose (dc) < 0) goto error;
@@ -2129,6 +2255,7 @@ UNUSED
SKIPPED();
puts(" Szip, shuffle, or fletcher32 checksum filter not enabled");
#endif /* H5_HAVE_FILTER_SZIP && H5_HAVE_FILTER_SHUFFLE && H5_HAVE_FILTER_FLETCHER32 */
+
return 0;
error:
@@ -4754,11 +4881,12 @@ test_types(hid_t file)
/* This message derives from H5Z */
const H5Z_class_t H5Z_CAN_APPLY_TEST[1] = {{
H5Z_CLASS_T_VERS,
- H5Z_FILTER_BOGUS, /* Filter id number */
+ H5Z_FILTER_BOGUS3, /* Filter id number */
1, 1,
"bogus", /* Filter name for debugging */
can_apply_bogus, /* The "can apply" callback */
NULL, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
filter_bogus, /* The actual filter function */
}};
@@ -4806,7 +4934,7 @@ test_can_apply(hid_t file)
printf(" Line %d: Can't register 'can apply' filter\n",__LINE__);
goto error;
}
- if(H5Pset_filter(dcpl, H5Z_FILTER_BOGUS, 0, (size_t)0, NULL) < 0) {
+ if(H5Pset_filter(dcpl, H5Z_FILTER_BOGUS3, 0, (size_t)0, NULL) < 0) {
H5_FAILED();
printf(" Line %d: Can't set bogus filter\n",__LINE__);
goto error;
@@ -5119,6 +5247,7 @@ const H5Z_class_t H5Z_SET_LOCAL_TEST[1] = {{
"bogus2", /* Filter name for debugging */
NULL, /* The "can apply" callback */
set_local_bogus2, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
filter_bogus2, /* The actual filter function */
}};
@@ -6480,10 +6609,10 @@ main(void)
#ifndef H5_NO_DEPRECATED_SYMBOLS
nerrors += (test_deprec(file) < 0 ? 1 : 0);
#endif /* H5_NO_DEPRECATED_SYMBOLS */
-
+
if(H5Fclose(file) < 0)
goto error;
- } /* end for */
+ } /* end for */
/* Close 2nd FAPL */
H5Pclose(fapl2);
@@ -6496,6 +6625,8 @@ main(void)
else
puts("All dataset tests skipped - Incompatible with current Virtual File Driver");
+ H5close();
+
return 0;
error:
diff --git a/test/tvltypes.c b/test/tvltypes.c
index 1ea0eaa..ffa6e56 100644
--- a/test/tvltypes.c
+++ b/test/tvltypes.c
@@ -544,6 +544,7 @@ test_vltypes_vlen_atomic(void)
} /* end test_vltypes_vlen_atomic() */
+
/****************************************************************
**
** rewrite_vltypes_vlen_atomic(): check memory leak for basic VL datatype.
@@ -699,7 +700,289 @@ rewrite_vltypes_vlen_atomic(void)
} /* end rewrite_vltypes_vlen_atomic() */
+/****************************************************************
+**
+** test_vltypes_modify_type(): Test H5Dmodify_dtype
+** Tests for VL datatypes of atomic datatypes
+** This test is disabled now because the library doesn't
+** support changing the base type of VL.
+**
+****************************************************************/
+#ifdef TMP
+static void
+test_vltypes_modify_type(void)
+{
+ hvl_t wdata[SPACE1_DIM1]; /* Information to write */
+ hvl_t wdata2[SPACE1_DIM1]; /* Information to write */
+ hvl_t rdata[SPACE1_DIM1]; /* Information read in */
+ hvl_t fill; /* Fill value */
+ hid_t fid1; /* HDF5 File IDs */
+ hid_t dataset; /* Dataset ID */
+ hid_t sid1; /* Dataspace ID */
+ hid_t sid2; /* ID of bad dataspace (no extent set) */
+ hid_t tid1, tid2; /* Datatype ID */
+ hid_t dcpl_pid; /* Dataset creation property list ID */
+ hid_t xfer_pid; /* Dataset transfer property list ID */
+ hsize_t dims1[] = {SPACE1_DIM1};
+ hsize_t chunk_dims1[] = {SPACE1_DIM1/4};
+ hsize_t size; /* Number of bytes which will be used */
+ unsigned i,j; /* counting variables */
+ size_t mem_used=0; /* Memory used during allocation */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing the H5Dmodify_dtype Functionality of Atomic VL Datatype\n"));
+
+ /* Allocate and initialize VL data to write */
+ for(i=0; i<SPACE1_DIM1; i++) {
+ wdata[i].p=HDmalloc((i+1)*sizeof(unsigned int));
+ wdata[i].len=i+1;
+ for(j=0; j<(i+1); j++)
+ ((unsigned int *)wdata[i].p)[j]=i*10+j;
+
+ wdata2[i].p=NULL;
+ wdata2[i].len=0;
+ } /* end for */
+
+ /* Create file */
+ fid1 = H5Fcreate(FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid1, FAIL, "H5Fcreate");
+
+ /* Create dataspace for datasets */
+ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
+ CHECK(sid1, FAIL, "H5Screate_simple");
+
+ /* Create a datatype to refer to */
+ tid1 = H5Tvlen_create (H5T_NATIVE_UINT);
+ CHECK(tid1, FAIL, "H5Tvlen_create");
+
+ /* Create a contiguous dataset */
+ dataset = H5Dcreate2(fid1, "Dataset1", tid1, sid1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(dataset, FAIL, "H5Dcreate");
+
+ /* Write dataset to disk */
+ ret=H5Dwrite(dataset,tid1,H5S_ALL,H5S_ALL,H5P_DEFAULT,wdata);
+ CHECK(ret, FAIL, "H5Dwrite");
+
+ /* Close Dataset */
+ ret = H5Dclose(dataset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Create second dataset, with fill value */
+ dcpl_pid=H5Pcreate(H5P_DATASET_CREATE);
+ CHECK(dcpl_pid, FAIL, "H5Pcreate");
+
+ /* Set chunking */
+ ret = H5Pset_layout(dcpl_pid, H5D_CHUNKED);
+ CHECK(ret, FAIL, "H5Pset_layout");
+
+ ret = H5Pset_chunk(dcpl_pid, 1, chunk_dims1);
+ CHECK(ret, FAIL, "H5Pset_chunk");
+
+ /* Create a chunked dataset */
+ dataset = H5Dcreate2(fid1, "Dataset2", tid1, sid1, H5P_DEFAULT, dcpl_pid, H5P_DEFAULT);
+ CHECK(dataset, FAIL, "H5Dcreate");
+
+ /* Close dataset creation property list */
+ ret = H5Pclose(dcpl_pid);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Write data to disk */
+ ret = H5Dwrite(dataset, tid1, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
+ CHECK(ret, FAIL, "H5Dwrite");
+
+ /* Close Dataset */
+ ret = H5Dclose(dataset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Close datatype */
+ ret = H5Tclose(tid1);
+ CHECK(ret, FAIL, "H5Tclose");
+
+ /* Close disk dataspace */
+ ret = H5Sclose(sid1);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Close file */
+ ret = H5Fclose(fid1);
+ CHECK(ret, FAIL, "H5Fclose");
+
+
+ /* Open the file for data checking */
+ fid1 = H5Fopen(FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(fid1, FAIL, "H5Fopen");
+
+ /* Create a new datatype to which the dataset will be changed */
+ tid2 = H5Tvlen_create (H5T_NATIVE_LLONG);
+ CHECK(tid2, FAIL, "H5Tvlen_create");
+
+ /* Open the contiguous dataset */
+ dataset = H5Dopen2(fid1, "Dataset1", H5P_DEFAULT);
+ CHECK(dataset, FAIL, "H5Dopen2");
+
+ /* Modify the datatype of the contiguous dataset now. It should
+ * immediately change the dataset's datatype and the data. */
+ ret = H5Dmodify_dtype(dataset, tid2);
+ CHECK(ret, FAIL, "H5Dmodify_dtype");
+
+ /* Get dataspace for datasets */
+ sid1 = H5Dget_space(dataset);
+ CHECK(sid1, FAIL, "H5Dget_space");
+
+ /* Get datatype for dataset */
+ tid1 = H5Dget_type(dataset);
+ CHECK(tid1, FAIL, "H5Dget_type");
+
+ /* Change to the custom memory allocation routines for reading VL data */
+ xfer_pid = H5Pcreate(H5P_DATASET_XFER);
+ CHECK(xfer_pid, FAIL, "H5Pcreate");
+
+ ret = H5Pset_vlen_mem_manager(xfer_pid, test_vltypes_alloc_custom, &mem_used, test_vltypes_free_custom, &mem_used);
+ CHECK(ret, FAIL, "H5Pset_vlen_mem_manager");
+
+ /* Make certain the correct amount of memory will be used */
+ ret = H5Dvlen_get_buf_size(dataset, tid1, sid1, &size);
+ CHECK(ret, FAIL, "H5Dvlen_get_buf_size");
+
+ /* 10 elements allocated = 1 + 2 + 3 + 4 elements for each array position */
+ VERIFY(size,((SPACE1_DIM1 * (SPACE1_DIM1 + 1)) / 2) * sizeof(long_long), "H5Dvlen_get_buf_size");
+
+ /* Read dataset from disk */
+ ret = H5Dread(dataset, tid1, H5S_ALL, H5S_ALL, xfer_pid, rdata);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Make certain the correct amount of memory has been used */
+ /* 10 elements allocated = 1 + 2 + 3 + 4 elements for each array position */
+ VERIFY(mem_used,((SPACE1_DIM1*(SPACE1_DIM1+1))/2)*sizeof(long_long),"H5Dread");
+
+ /* Compare data read in */
+ for(i=0; i<SPACE1_DIM1; i++) {
+ if(wdata[i].len!=rdata[i].len) {
+ TestErrPrintf("%d: VL data lengths don't match!, wdata[%d].len=%d, rdata[%d].len=%d\n",__LINE__,(int)i,(int)wdata[i].len,(int)i,(int)rdata[i].len);
+ continue;
+ } /* end if */
+ for(j=0; j<rdata[i].len; j++) {
+ if( ((unsigned int *)wdata[i].p)[j] != ((long_long *)rdata[i].p)[j] ) {
+ TestErrPrintf("VL data values don't match!, wdata[%d].p[%d]=%d, rdata[%d].p[%d]=%d\n",(int)i,(int)j, (int)((unsigned int *)wdata[i].p)[j], (int)i,(int)j, (int)((long_long *)rdata[i].p)[j]);
+ continue;
+ } /* end if */
+ } /* end for */
+ } /* end for */
+
+ /* Reclaim the read VL data */
+ ret = H5Dvlen_reclaim(tid1, sid1, xfer_pid, rdata);
+ CHECK(ret, FAIL, "H5Dvlen_reclaim");
+
+ /* Make certain the VL memory has been freed */
+ VERIFY(mem_used, 0, "H5Dvlen_reclaim");
+
+ /* Close Dataset */
+ ret = H5Dclose(dataset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Close datatype */
+ ret = H5Tclose(tid1);
+ CHECK(ret, FAIL, "H5Tclose");
+
+ /* Close disk dataspace */
+ ret = H5Sclose(sid1);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Close dataset transfer property list */
+ ret = H5Pclose(xfer_pid);
+ CHECK(ret, FAIL, "H5Pclose");
+
+
+ /* Open the chunked dataset */
+ dataset = H5Dopen2(fid1, "Dataset2", H5P_DEFAULT);
+ CHECK(dataset, FAIL, "H5Dopen2");
+
+ /* Modify the datatype of the chunked dataset now. It should
+ * immediately change the dataset's datatype and the data. */
+ ret = H5Dmodify_dtype(dataset, tid2);
+ CHECK(ret, FAIL, "H5Dmodify_dtype");
+
+ /* Get dataspace for datasets */
+ sid1 = H5Dget_space(dataset);
+ CHECK(sid1, FAIL, "H5Dget_space");
+
+ /* Get datatype for dataset */
+ tid1 = H5Dget_type(dataset);
+ CHECK(tid1, FAIL, "H5Dget_type");
+
+ /* Change to the custom memory allocation routines for reading VL data */
+ xfer_pid = H5Pcreate(H5P_DATASET_XFER);
+ CHECK(xfer_pid, FAIL, "H5Pcreate");
+
+ ret = H5Pset_vlen_mem_manager(xfer_pid, test_vltypes_alloc_custom, &mem_used, test_vltypes_free_custom, &mem_used);
+ CHECK(ret, FAIL, "H5Pset_vlen_mem_manager");
+
+ /* Make certain the correct amount of memory will be used */
+ ret = H5Dvlen_get_buf_size(dataset, tid1, sid1, &size);
+ CHECK(ret, FAIL, "H5Dvlen_get_buf_size");
+
+ /* 10 elements allocated = 1 + 2 + 3 + 4 elements for each array position */
+ VERIFY(size,((SPACE1_DIM1*(SPACE1_DIM1+1))/2)*sizeof(long_long),"H5Dvlen_get_buf_size");
+
+ /* Read dataset from disk */
+ ret=H5Dread(dataset,tid1,H5S_ALL,H5S_ALL,xfer_pid,rdata);
+ CHECK(ret, FAIL, "H5Dread");
+
+ /* Make certain the correct amount of memory has been used */
+ /* 10 elements allocated = 1 + 2 + 3 + 4 elements for each array position */
+ VERIFY(mem_used,((SPACE1_DIM1*(SPACE1_DIM1+1))/2)*sizeof(long_long),"H5Dread");
+
+ /* Compare data read in */
+ for(i=0; i<SPACE1_DIM1; i++) {
+ if(wdata[i].len!=rdata[i].len) {
+ TestErrPrintf("%d: VL data lengths don't match!, wdata[%d].len=%d, rdata[%d].len=%d\n",__LINE__,(int)i,(int)wdata[i].len,(int)i,(int)rdata[i].len);
+ continue;
+ } /* end if */
+ for(j=0; j<rdata[i].len; j++) {
+ if( ((unsigned int *)wdata[i].p)[j] != ((long_long *)rdata[i].p)[j] ) {
+ TestErrPrintf("VL data values don't match!, wdata[%d].p[%d]=%d, rdata[%d].p[%d]=%d\n",(int)i,(int)j, (int)((unsigned int *)wdata[i].p)[j], (int)i,(int)j, (int)((long_long *)rdata[i].p)[j]);
+ continue;
+ } /* end if */
+ } /* end for */
+ } /* end for */
+
+ /* Reclaim the read VL data */
+ ret=H5Dvlen_reclaim(tid1,sid1,xfer_pid,rdata);
+ CHECK(ret, FAIL, "H5Dvlen_reclaim");
+
+ /* Make certain the VL memory has been freed */
+ VERIFY(mem_used,0,"H5Dvlen_reclaim");
+
+ /* Close Dataset */
+ ret = H5Dclose(dataset);
+ CHECK(ret, FAIL, "H5Dclose");
+
+ /* Reclaim the write VL data */
+ ret=H5Dvlen_reclaim(tid1,sid1,H5P_DEFAULT,wdata);
+ CHECK(ret, FAIL, "H5Dvlen_reclaim");
+
+ /* Close datatype */
+ ret = H5Tclose(tid1);
+ CHECK(ret, FAIL, "H5Tclose");
+
+ /* Close datatype */
+ ret = H5Tclose(tid2);
+ CHECK(ret, FAIL, "H5Tclose");
+
+ /* Close disk dataspace */
+ ret = H5Sclose(sid1);
+ CHECK(ret, FAIL, "H5Sclose");
+
+ /* Close dataset transfer property list */
+ ret = H5Pclose(xfer_pid);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close file */
+ ret = H5Fclose(fid1);
+ CHECK(ret, FAIL, "H5Fclose");
+} /* end test_vltypes_modify_type() */
+#endif /* TMP */
/****************************************************************
**
@@ -3166,6 +3449,8 @@ test_vltypes(void)
test_vltypes_compound_vlen_vlen();/* Test compound datatypes with VL atomic components */
test_vltypes_compound_vlstr(); /* Test data rewritten of nested VL data */
test_vltypes_fill_value(); /* Test fill value for VL data */
+ /* Disable this test because the library doesn't support changing the base type of VL */
+ /*test_vltypes_modify_type();*/ /* Test H5Dmodify_dtype with VL atomic datatypes */
} /* test_vltypes() */
diff --git a/testpar/Makefile.in b/testpar/Makefile.in
index ba73cb2..60c1851 100644
--- a/testpar/Makefile.in
+++ b/testpar/Makefile.in
@@ -235,6 +235,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/testpar/t_dset.c b/testpar/t_dset.c
index ce4742b..c149ae0 100644
--- a/testpar/t_dset.c
+++ b/testpar/t_dset.c
@@ -1842,7 +1842,7 @@ extend_writeAll(void)
H5Sclose(mem_dataspace);
H5Pclose(xfer_plist);
-
+#ifdef TMP
/* -------------------------
* Test writing to dataset2
* -------------------------*/
@@ -1916,7 +1916,7 @@ extend_writeAll(void)
VRFY((ret >= 0), "H5Sclose succeeded");
ret = H5Pclose(xfer_plist);
VRFY((ret >= 0), "H5Pclose succeeded");
-
+#endif /*TMP*/
/* close dataset collectively */
ret = H5Dclose(dataset1);
diff --git a/testpar/testphdf5.c b/testpar/testphdf5.c
index 2f74221..c83f4f0 100644
--- a/testpar/testphdf5.c
+++ b/testpar/testphdf5.c
@@ -138,8 +138,10 @@ parse_options(int argc, char **argv)
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
/* setup default chunk-size. Make sure sizes are > 0 */
- chunkdim0 = (dim0+9)/10;
- chunkdim1 = (dim1+9)/10;
+ chunkdim0 = dim0/3;
+ chunkdim1 = dim1/3;
+ /*chunkdim0 = (dim0+9)/10;
+ chunkdim1 = (dim1+9)/10;*/
while (--argc){
if (**(++argv) != '-'){
@@ -188,8 +190,10 @@ parse_options(int argc, char **argv)
argc--;
dim1 = atoi(*(++argv));
/* set default chunkdim sizes too */
- chunkdim0 = (dim0+9)/10;
- chunkdim1 = (dim1+9)/10;
+ chunkdim0 = dim0/3;
+ chunkdim1 = dim1/3;
+ /*chunkdim0 = (dim0+9)/10;
+ chunkdim1 = (dim1+9)/10;*/
break;
case 'c': /* chunk dimensions */
if (--argc < 2){
diff --git a/tools/Makefile.in b/tools/Makefile.in
index eabfca2..c2ca008 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -199,6 +199,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/tools/h5copy/Makefile.in b/tools/h5copy/Makefile.in
index 9eb5425..a7c6c11 100644
--- a/tools/h5copy/Makefile.in
+++ b/tools/h5copy/Makefile.in
@@ -216,6 +216,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/tools/h5diff/Makefile.in b/tools/h5diff/Makefile.in
index 79c6ab6..bff8ea4 100644
--- a/tools/h5diff/Makefile.in
+++ b/tools/h5diff/Makefile.in
@@ -223,6 +223,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/tools/h5dump/Makefile.in b/tools/h5dump/Makefile.in
index 4bb4ad9..f2c06f9 100644
--- a/tools/h5dump/Makefile.in
+++ b/tools/h5dump/Makefile.in
@@ -221,6 +221,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c
index 3bcb40a..392421b 100644
--- a/tools/h5dump/h5dump.c
+++ b/tools/h5dump/h5dump.c
@@ -2637,6 +2637,10 @@ dump_dcpl(hid_t dcpl_id,hid_t type_id, hid_t obj_id)
indentation(indent + COL);
printf("%s %s %s %d %s\n", SCALEOFFSET, BEGIN, SCALEOFFSET_MINBIT, cd_values[0], END);
break;
+ case H5Z_FILTER_DTYPE_MODIFY:
+ indentation(indent + COL);
+ printf("%s\n", DTYPE_MODIFY);
+ break;
default:
indentation(indent + COL);
if (H5Zfilter_avail(filtn))
diff --git a/tools/h5dump/h5dump.h b/tools/h5dump/h5dump.h
index e16705c..76866bc 100644
--- a/tools/h5dump/h5dump.h
+++ b/tools/h5dump/h5dump.h
@@ -62,6 +62,7 @@
#define NBIT "COMPRESSION NBIT"
#define SCALEOFFSET "COMPRESSION SCALEOFFSET"
#define SCALEOFFSET_MINBIT "MIN BITS"
+#define DTYPE_MODIFY "MODIFY DSET'S TYPE"
#define STORAGE_LAYOUT "STORAGE_LAYOUT"
#define CONTIGUOUS "CONTIGUOUS"
#define COMPACT "COMPACT"
diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c
index 516a740..f72fe8f 100644
--- a/tools/h5dump/h5dumpgentest.c
+++ b/tools/h5dump/h5dumpgentest.c
@@ -110,7 +110,7 @@ myfilter(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
/* a "set local" callback */
static herr_t
-set_local_myfilter(hid_t dcpl_id, hid_t tid, hid_t UNUSED sid);
+set_local_myfilter(hid_t dcpl_id, hid_t tid, hid_t UNUSED sid, hid_t UNUSED file_id);
#define MYFILTER_ID 405
@@ -122,6 +122,7 @@ const H5Z_class_t H5Z_MYFILTER[1] = {{
"myfilter", /* Filter name for debugging */
NULL, /* The "can apply" callback */
set_local_myfilter, /* The "set local" callback */
+ NULL, /* The "reset local" callback */
myfilter, /* The actual filter function */
}};
@@ -4727,7 +4728,6 @@ static void gent_filters(void)
assert(ret >= 0);
#endif
-
/*-------------------------------------------------------------------------
* shuffle
*-------------------------------------------------------------------------
@@ -4745,7 +4745,6 @@ static void gent_filters(void)
assert(ret >= 0);
#endif
-
/*-------------------------------------------------------------------------
* checksum
*-------------------------------------------------------------------------
@@ -4843,7 +4842,6 @@ static void gent_filters(void)
ret=make_dset(fid,"all",sid,H5T_NATIVE_INT,dcpl,buf1);
assert(ret >= 0);
-
/*-------------------------------------------------------------------------
* user defined filter
*-------------------------------------------------------------------------
@@ -4952,7 +4950,7 @@ myfilter(unsigned int UNUSED flags, size_t UNUSED cd_nelmts,
*/
static herr_t
-set_local_myfilter(hid_t dcpl_id, hid_t UNUSED tid, hid_t UNUSED sid)
+set_local_myfilter(hid_t dcpl_id, hid_t UNUSED tid, hid_t UNUSED sid, hid_t UNUSED file_id)
{
unsigned flags; /* Filter flags */
size_t cd_nelmts = 0; /* Number of filter parameters */
diff --git a/tools/h5import/Makefile.in b/tools/h5import/Makefile.in
index 159e151..60f3dfb 100755
--- a/tools/h5import/Makefile.in
+++ b/tools/h5import/Makefile.in
@@ -216,6 +216,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/tools/h5jam/Makefile.in b/tools/h5jam/Makefile.in
index 83555b1..a5924fb 100644
--- a/tools/h5jam/Makefile.in
+++ b/tools/h5jam/Makefile.in
@@ -227,6 +227,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/tools/h5ls/Makefile.in b/tools/h5ls/Makefile.in
index 605793a..a7cc576 100644
--- a/tools/h5ls/Makefile.in
+++ b/tools/h5ls/Makefile.in
@@ -210,6 +210,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/tools/h5repack/Makefile.in b/tools/h5repack/Makefile.in
index 30f7b32..a285bc5 100644
--- a/tools/h5repack/Makefile.in
+++ b/tools/h5repack/Makefile.in
@@ -230,6 +230,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/tools/h5stat/Makefile.in b/tools/h5stat/Makefile.in
index 33a3060..edc3043 100644
--- a/tools/h5stat/Makefile.in
+++ b/tools/h5stat/Makefile.in
@@ -219,6 +219,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/tools/lib/Makefile.in b/tools/lib/Makefile.in
index 8de1275..cc0af31 100644
--- a/tools/lib/Makefile.in
+++ b/tools/lib/Makefile.in
@@ -215,6 +215,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@
diff --git a/tools/lib/h5tools_filters.c b/tools/lib/h5tools_filters.c
index 325023d..000ef0d 100644
--- a/tools/lib/h5tools_filters.c
+++ b/tools/lib/h5tools_filters.c
@@ -55,6 +55,7 @@ int h5tools_canreadf(const char* name, /* object name, serves also as boolean pr
int have_fletcher=0;
int have_nbit=0;
int have_scaleoffset=0;
+ int have_dtype_modify=0;
#ifdef H5_HAVE_FILTER_DEFLATE
have_deflate=1;
@@ -74,7 +75,9 @@ int h5tools_canreadf(const char* name, /* object name, serves also as boolean pr
#ifdef H5_HAVE_FILTER_SCALEOFFSET
have_scaleoffset=1;
#endif
-
+#ifdef H5_HAVE_FILTER_DTYPE_MODIFY
+ have_dtype_modify=1;
+#endif
/* get information about filters */
if ((nfilters = H5Pget_nfilters(dcpl_id))<0)
@@ -173,6 +176,18 @@ int h5tools_canreadf(const char* name, /* object name, serves also as boolean pr
return 0;
}
break;
+/*-------------------------------------------------------------------------
+ * H5Z_FILTER_DTYPE_MODIFY
+ *-------------------------------------------------------------------------
+ */
+ case H5Z_FILTER_DTYPE_MODIFY:
+ if (!have_dtype_modify)
+ {
+ if (name)
+ print_warning(name,"dtype_modify");
+ return 0;
+ }
+ break;
}/*switch*/
}/*for*/
@@ -204,6 +219,7 @@ int h5tools_can_encode( H5Z_filter_t filtn)
int have_fletcher=0;
int have_nbit=0;
int have_scaleoffset=0;
+ int have_dtype_modify=0;
unsigned int filter_config_flags;
#ifdef H5_HAVE_FILTER_DEFLATE
@@ -224,6 +240,9 @@ int h5tools_can_encode( H5Z_filter_t filtn)
#ifdef H5_HAVE_FILTER_SCALEOFFSET
have_scaleoffset=1;
#endif
+#ifdef H5_HAVE_FILTER_DTYPE_MODIFY
+ have_dtype_modify=1;
+#endif
switch (filtn)
{
@@ -288,6 +307,12 @@ int h5tools_can_encode( H5Z_filter_t filtn)
return 0;
}
break;
+ case H5Z_FILTER_DTYPE_MODIFY:
+ if (!have_dtype_modify)
+ {
+ return 0;
+ }
+ break;
}/*switch*/
return 1;
diff --git a/tools/misc/Makefile.in b/tools/misc/Makefile.in
index 44d54c0..03d614d 100644
--- a/tools/misc/Makefile.in
+++ b/tools/misc/Makefile.in
@@ -234,6 +234,7 @@ TIME = @TIME@
TR = @TR@
TRACE_API = @TRACE_API@
USE_FILTER_DEFLATE = @USE_FILTER_DEFLATE@
+USE_FILTER_DTYPE_MODIFY = @USE_FILTER_DTYPE_MODIFY@
USE_FILTER_FLETCHER32 = @USE_FILTER_FLETCHER32@
USE_FILTER_NBIT = @USE_FILTER_NBIT@
USE_FILTER_SCALEOFFSET = @USE_FILTER_SCALEOFFSET@