diff options
97 files changed, 4437 insertions, 315 deletions
@@ -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 */ }}; @@ -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, @@ -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; @@ -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) @@ -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 @@ -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@ |